World.of.Warcraft.Programming.A.Guide.and.Reference.for.Creating.Wo W.Addons

World.of.Warcraft.Programming.A.Guide.and.Reference.for.Creating.WoW.Addons

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 1443 [warning: Documents this large are best viewed by clicking the View PDF Link!]

James Whitehead II
Rick Roe
A Guide and Reference for Creating WoW Addons
Whitehead • Roe
$49.99 US • $59.99 CAN
Computer Graphics / Game Programming
Visit our Web site at www.wiley.com/compbooks
Front cover art © Scott Johnson/FrogPants Studios
®
Your secret weapon against
the Lich King’s wrath
World of Warcraft has entered a new dimension. Take command of it by modifying the interface
with your own unique addons. Whether your goal is to enhance addons you already use, to
enlarge your arsenal by creating some all-new features, or to immerse yourself in the programming
as well as the game, this book will be your oracle. Learn the arcane languages of Lua and XML
and master the craft of addon creation!
Understand the anatomy of an addon
Work with frames, widgets, and other graphical elements
Explore basic and advanced functions and control structures
Track damage with CombatTracker, and respond to the combat log
and threat information
Track, lter, and sort your inventory by writing BagBuddy,
a fully functional addon
Create slash commands, custom graphics, scroll frames, and
dropdown menus
Who are you?
Apprentice programmers with no prior experience — learn Lua and XML in Part I
Journeymen who have done some programming — skim Part I and start with the details about addon creation in Part II
Master programmers with addons already in their arsenal — dive right into Advanced Addon Techniques in Part III
James Whitehead II, aka Cladhaire, is the creator of PerfectRaid, Clique, TomTom, and LightHeaded, and coauthor of
Hacking
World of Warcraft
.
Rick Roe, aka the crazy goblin tinker Gazmik Fizzwidget, created Feed-O-Matic, FactionFriend, and some other addons so
awesome that Blizzard rolled their functionality into its new UI.
®
World of Warcraft®
Programming
World of Warcraft®
Programming
A Guide and Reference for Creating
WoW Addons
Second Edition
James Whitehead II
Rick Roe
Wiley Publishing, Inc.
World of Warcraft®Programming: A Guide and Reference for Creating WoW Addons, Second Edition
Published by
Wiley Publishing, Inc.
10475 Crosspoint Boulevard
Indianapolis, IN 46256
www.wiley.com
Copyright ©2010 by Wiley Publishing, Inc., Indianapolis, Indiana
Published simultaneously in Canada
ISBN: 978-0-470-48128-8
Manufactured in the United States of America
10987654321
No part of this publication may be reproduced, stored in a retrieval system or transmitted in any form or by any means,
electronic, mechanical, photocopying, recording, scanning or otherwise, except as permitted under Sections 107 or 108
of the 1976 United States Copyright Act, without either the prior written permission of the Publisher, or authorization
through payment of the appropriate per-copy fee to the Copyright Clearance Center, 222 Rosewood Drive, Danvers,
MA 01923, (978) 750-8400, fax (978) 646-8600. Requests to the Publisher for permission should be addressed to the
Permissions Department, John Wiley & Sons, Inc., 111 River Street, Hoboken, NJ 07030, (201) 748-6011, fax (201) 748-6008,
or online at http://www.wiley.com/go/permissions.
Limit of Liability/Disclaimer of Warranty: The publisher and the author make no representations or warranties with
respect to the accuracy or completeness of the contents of this work and specifically disclaim all warranties, including
without limitation warranties of fitness for a particular purpose. No warranty may be created or extended by sales or
promotional materials. The advice and strategies contained herein may not be suitable for every situation. This work
is sold with the understanding that the publisher is not engaged in rendering legal, accounting, or other professional
services. If professional assistance is required, the services of a competent professional person should be sought. Neither
the publisher nor the author shall be liable for damages arising herefrom. The fact that an organization or Web site is
referred to in this work as a citation and/or a potential source of further information does not mean that the author or the
publisher endorses the information the organization or Web site may provide or recommendations it may make. Further,
readers should be aware that Internet Web sites listed in this work may have changed or disappeared between when this
work was written and when it is read.
For general information on our other products and services please contact our Customer Care Department within the
United States at (877) 762-2974, outside the United States at (317) 572-3993 or fax (317) 572-4002.
Wiley also publishes its books in a variety of electronic formats. Some content that appears in print may not be available
in electronic books.
Library of Congress Control Number: 2009933378
Trademarks: Wiley and the Wiley logo are trademarks or registered trademarks of John Wiley & Sons, Inc. and/or its
affiliates, in the United States and other countries, and may not be used without written permission. All other trademarks
are the property of their respective owners. Wiley Publishing, Inc. is not associated with any product or vendor mentioned
in this book.
About the Authors
James Whitehead II is the author of a number of popular addons for World
of Warcraft, including LightHeaded, TomTom, Clique, PerfectRaid, and many
other small but useful addons. He has been an active member of both the WoW
UI and Lua communities since the World of Warcraft Beta began and has been
writing addons ever since. When he actually has time to play the game, you
can find him playing one of his many characters on the Emerald Dream (EU)
server.
Jim currently resides in Oxford, England where he is pursuing his DPhil
(PhD) in Computer Science at the Computing Laboratory. In his spare time he
enjoys all things rowing, hacking on his Android phone, knitting, crocheting,
and spending time with his friends.
Rick Roeknown in the WoW UI community as the zany goblin tinker
Gazmik Fizzwidgetis the author of several popular addons including
Feed-O-Matic and FactionFriend, as well as TrackMenu and a couple of
others so useful that Blizzard made them obsolete by rolling their functionality
into the default UI. When not slaving away for their goblin master, Rick’s alter
egos can often be found adventuring on Cenarius US.
Rick currently resides in Vancouver, Washington, with his wife and cats.
His time outside of Azeroth is split between working to finish a computer
science degree at Washington State University and building Mac and iPhone
applications as an independent software developer.
v
About the Technical Editors
Daniel Stephensmore widely known in the WoW addon community as
Irielwas the Blizzard WoW UI Forum’s first MVP. He has been helping
others develop addons for several years, creating a few of his own along the
way. His addons include DevTools (recently rolled into the base WoW UI)
and he has made significant contributions to secure handlers and a number of
other utilities. As somewhat of an altaholic, he has characters spread all over
the realms, but considers Silver Hand (US) his original WoW home.
Daniel lives in the San Francisco bay area with his wife, cats, and camera. He
spends his ‘‘not free’’ time doing systems design, architecture, and occasionally
development work.
Esteban Santana Santana, known online as MentalPower, is both Lead Devel-
oper for the Auctioneer AddOns Package and one of the Administrators
of Norganna’s AddOns. He’s been part of the WoW UI community since
mid-2005 and has helped many people via the IRC channels and the various
game and UI-related forums. When he logs into World of Warcraft, you can
find him on the US-Alleria realm trying to level his various characters on the
Emerald Dream guild.
Esteban currently resides in Carolina, Puerto Rico, and is a jack-of-all-trades
IT person for Liberty Cablevision. In his spare time, he enjoys thrashing his
buddies in a good game of Rock Band on the XBox 360.
vi
Credits
Acquisitions Editor
Scott Meyers
Contributing Author
Nevin Flanagan
Project Editor
Maryann Steinhart
Technical Editors
Daniel Stephens
Rick Roe
Esteban Santana Santana
Production Editor
Rebecca Anderson
Copy Editor
Kim Cofer
Editorial Director
Robyn B. Siesky
Editorial Manager
Mary Beth Wakefield
Associate Director of Marketing
David Mayhew
Production Manager
Tim Tate
Vice President and Executive
Group Publisher
Richard Swadley
Vice President and Executive
Publisher
Barry Pruett
Associate Publisher
Jim Minatel
Project Coordinator, Cover
Lynsey Stanford
Proofreaders
Josh Chase and Nelson Kim, Word
One
Indexer
J&JIndexing
Cover Image
Scott Johnson, FrogPants Studios
LLC
Cover Designer
Michael E. Trent
vii
Acknowledgments
James and Lee Whitehead, thank you for walking alongside your children as
we journey down the winding road of life; we’re blessed to have the two of
you in our lives. Michelle Hastings, thank you for being such a role model
of strength and determination for your little brother.
Robert Whitehead, thank you for always being yourself and making sure
I don’t stray far from who I am. Gregory Whitehead, thank you for being there
for me whenever I need to ‘‘geek’’ out, I don’t know many people that can get
as excited as I do about silly things. Tom Harper, thank you for what you give
me every single day. Everything about you makes me feel like the luckiest
person alive.
Jamie Anderson, Edward Wilman, Amelia Earl, Rhianedd Jewell, Erika
Nitsch, Daniel Jordan, and all my other friends at Oxford, thank you for
keeping me busy, for helping me make excuses, and for being such a bad
influence.
To Karen Hobson and everyone at WowInterface who have put up with me
for five years now, thank you for all of your efforts in organizing all three
books. To Mike, Kevin, Tom, Jacob, Sam, and everyone at Blizzard, thank you
for creating such an amazing game and supporting us in our documentation
efforts. To everyone at Wiley who helped bring these books into existence,
thank you for your efforts to provide resources for the WoW user interface
community. To Rick, thank you for stepping in when we needed you the most;
your work has been instrumental in making this book what it is today. To
Daniel, Nevin, and Esteban, thank you for all of your help in shaping the edges
of this edition.
Finally, thank you to the World of Warcraft user interface community for
everything you do.
—Jim
ix
x Acknowledgments
I’d first like to thank my coauthor, Jim, for offering me the opportunity to
‘‘graduate’’ from tech editing on the first edition to authoring on this second
version. Crazy as the schedules and deadlines may have been, I’m still happier
having been able to write my part instead of worrying about mucking with
someone else’s work in order to satisfymynitpickytendencies.Thanksalso
for all your infrastructure workwithout your website and database I’d have
been a scribe without paper.
To Daniel and Esteban fell the unenviable task of performing the role I did
on the first editioncatching all the silly code errors and obtuse explanations
we dumb authors makeand with it my sympathy and gratitude. I can but
hope I haven’t made your work too hard.
Thanks to Karen for playing den mother to the rowdy WoW UI community
and giving us all a place to hook up; if it weren’t for your efforts I’d never
have found my way into this project. Thanks as well to Scott, Maryann, and
everyone at Wiley for making the project happen!
Thanks (again) to Daniel and Jim not just for your work on the book but for
providing development tools without which my tasks would’ve been a whole
lot harder. And of course, thanks to my family,Karen,Doug,andBrad,for
putting up with me for a couple decades and making me the person I am,
and to my wonderful wife Anne: I can’t imagine life without you, much less
without the loving support you give for whatever crazy ideas I set myself to.
Finally, a very special thank you to Mike, Jacob, Sam, and Tom at Blizzard,
without whose patience and willingness to answer oblique questions outside
a normal work schedule we wouldn’t have been able to figure out several
important chunks of the API we’re documenting. Next time I’m in SoCal, your
drinks are on my tab.
—Rick
Contents at a Glance
Introduction xxxvii
Part I Learning to Program 1
Chapter 1 Programming for World of Warcraft 3
Chapter 2 Exploring Lua Basics 13
Chapter 3 Basic Functions and Control Structures 39
Chapter 4 Working with Tables 53
Chapter 5 Advanced Functions and Control Structures 77
Chapter 6 Lua Standard Libraries 91
Chapter 7 Learning XML 111
Part II Programming in World of Warcraft 123
Chapter 8 Anatomy of an Addon 125
Chapter 9 Working with Frames, Widgets, and Other Graphical
Elements 143
Chapter 10 Saving Time with Frame Templates 171
Chapter 11 Exploring the World of Warcraft API 187
Chapter 12 Interacting with Widgets 207
xi
xii Contents at a Glance
Chapter 13 Responding to Game Events 243
Chapter 14 Tracking Damage with CombatTracker 267
Part III Advanced Addon Techniques 283
Chapter 15 Taking Action with Secure Templates 285
Chapter 16 Binding Keys and Clicks to Addon Code 309
Chapter 17 Creating Slash Commands 337
Chapter 18 Responding to Graphic Updates with OnUpdate 351
Chapter 19 Altering Existing Behavior with Function Hooking 359
Chapter 20 Creating Custom Graphics 373
Chapter 21 Responding to the Combat Log and Threat Information 387
Chapter 22 Creating Scroll Frames 413
Chapter 23 Creating Dropdown Menus 431
Chapter 24 Scanning and Constructing Tooltips 451
Chapter 25 Taking Protected Action in Combat 463
Chapter 26 Creating Unit Frames with Group Templates 501
Part IV Reference 537
Chapter 27 API Reference 539
Chapter 28 API Categories 1025
Chapter 29 Widget Reference 1121
Chapter 30 Events Reference 1277
Part V Appendixes 1303
Appendix A Best Practices 1305
Appendix B Utilizing Addon Libraries 1329
Appendix C Tracking History Using Version Control Systems 1339
Appendix D Addon Author Resources 1349
Index 1357
Contents
Introduction xxxvii
Part I Learning to Program 1
Chapter 1 Programming for World of Warcraft 3
Customizing the User Interface 3
What Is an Addon? 4
What Can Addons Do? 4
Exploring Your AddOns Directory 7
Blizzard Addons 8
Custom Addons 10
Creating Your First Addon: HeyThere 10
Creating Files and Directories 10
Loading and Testing the Addon 11
Summary 12
Chapter 2 Exploring Lua Basics 13
Downloading and Installing Lua 14
Downloading and Installing WowLua 14
Using Lua on the Web 15
Downloading and Installing a Lua Interpreter 16
Microsoft Windows 16
Mac OS X 16
Using the Lua Interpreter 17
Running Commands 18
Understanding Error Messages 18
xiii
xiv Contents
Using History to Make Changes 19
Quitting the Interpreter 19
Microsoft Windows 19
Mac OS X 19
Working with Numbers 20
Basic Arithmetic Operations 20
Scientific Notation 21
Hexadecimal Notation 21
Understanding Floating Point 22
Understanding Values and Variables 23
Exploring Values and Their Types 23
Primitive Types 23
Using the type() Function 23
Using Variables 24
Valid Variable Names 25
Assigning Variables 25
Assigning Multiple Variables 26
Comparing Values 26
Working with Strings 27
Comparing Strings 27
Concatenating Multiple Strings 28
Converting Numbers to Strings 28
Converting Strings to Numbers 29
Quoting Strings 29
Single Quote (’) 29
Double Quote (’’) 30
Bracket Quote ([[ ]]) 30
Escaping Special Characters 31
Getting a String’s Length 32
Boolean Values and Operators 33
Using the and Operator 33
Using the or Operator 34
Negation Using the not Operator 34
Understanding the nil Value 35
Exploring Scope 35
Blocks 36
Chunks 37
Summary 37
Chapter 3 Basic Functions and Control Structures 39
Using Functions 39
Creating a Function 39
Local Functions 40
Contents xv
Function Arguments and Returns 41
Converting Celsius to Fahrenheit 41
Empty Arguments 42
No Return Values 42
FunctionsasLuaValues 42
Making Decisions with the if Statement 43
Simple Conditionals 43
Complex Expressions 44
Extended Conditionals 44
Displaying a Personalized Greeting 45
Repeating Actions with the while Statement 46
Computing Factorials 46
Differences Between while and repeat 47
Looping with the Numeric for Statement 48
Computing Factorials 50
Evaluation of Loop Conditions 50
Variable Scope in for Loops 50
Summary 51
Chapter 4 Working with Tables 53
Storing Data Using Tables 53
Creating and Indexing Tables 54
Clearing an Element from a Table 54
Shortcuts for String Keys 55
Creating Populated Tables 55
Using Tables as Arrays 56
Creating an Array 57
Getting the Length of an Array 57
Adding Elements to an Array 58
Removing Elements from an Array 60
Sorting the Elements of an Array 61
Using Tables as Namespaces 61
Creating a Namespace of Utility Functions 62
Adding Functions to a Namespace 62
Storing an Existing Function 62
Defining a New Function 63
Object-Oriented Programming with Tables 63
Creating a Non-Object-Oriented Counter 63
Using Tables as Simple Objects 64
Using : to Call Object Methods 65
Defining Functions Using : 66
Making a Better Counter 67
xvi Contents
Extending Tables with Metatables 68
Adding a Metatable 68
Defining Metamethods 69
Defining Basic Arithmetic Using ___add, ___sub, ___mul,
and ___div 70
Defining Negation Using ___unm 71
Creating Meaningful Output with ___tostring 71
Concatenating Tables Using ___concat 72
Exploring Fallback Tables with ___index 72
Catching Creation of Keys with ___newindex 74
Bypassing Metatables 75
value = rawget(tbl, key) 75
rawset(tbl, key, value) 76
Summary 76
Chapter 5 Advanced Functions and Control Structures 77
Multiple Return Values 77
Converting Hex to RGB 77
Assigning Multiple Values 78
Missing Return Values? 79
Multiple Return Values in World of Warcraft 79
Using a Dummy Variable 80
Using the select() Function 81
Accepting a Variable Number of Arguments 81
Declaring a Vararg Function 82
Using select() with ... 83
Generic for Loops and Iterators 84
Syntax of Generic for 84
Traversing the Array Part of a Table 85
Traversing an Entire Table 86
Clearing a Table 86
Using Other Iterators 87
Sorting an Array of Table Data 87
Define Example Data 88
Default Sort Order 88
Creating a Comparison Function 88
Creating a More Complex Sort Function 89
Summary 90
Chapter 6 Lua Standard Libraries 91
Table Library 92
str = table.concat (table [, sep [, i [, j]]]) 92
table.insert (table, [pos,] value) 92
max = table.maxn (table) 93
Contents xvii
value = table.remove (table [, pos]) 93
table.sort (table [, comp]) 93
String Utility Functions 94
Formatting New Strings 95
Pattern Matching 98
Character Classes 98
Pattern Items 100
Pattern Captures 101
Pattern Anchors 102
Pattern Examples 102
Pattern Matching Functions 102
string.gmatch(s, pattern) 103
string.gsub(s, pattern, repl [, n]) 103
string.match(s, pattern [, init]) 104
string.find(s, pattern [, init [, plain]]) 104
Math Library 105
World of Warcraft Additions to Lua 108
Function Aliases 109
Summary 110
Chapter 7 Learning XML 111
XML as a Markup Language 111
XML’s Relationship to HTML 112
Components of XML 112
XML Tags 113
XML Elements 113
XML Attributes 113
XML Entities 114
Creating Well-Formed XML 114
Validating an XML Document 115
Example Schema Definition 115
Example XML Document 116
Exploring the Schema 116
XML in World of Warcraft 117
Using a GradientType 118
Exploring Blizzard’s XML User Interface Customization Tool 119
Summary 121
Part II Programming in World of Warcraft 123
Chapter 8 Anatomy of an Addon 125
Exploring an Addon’s Files and Folders 125
Table of Contents (.toc) File 125
## Interface: 126
xviii Contents
## Title: 127
## Notes: 128
## Dependencies:, ## RequiredDeps: 128
## OptionalDeps: 129
## LoadOnDemand: 129
## LoadsWith: 129
## DefaultState: 130
## LoadManager: 130
## SavedVariables: 130
## SavedVariablesPerCharacter: 131
X-Label Directives 131
Addon Categories 131
XML Files 132
Lua Script Files 133
Media Files 133
Music 133
Graphics 133
Localizing Your Addons 134
Valid Locales 135
Reasons for Providing Localization 135
Encouraging Users to Contribute 136
Implementing Localization 136
Add a File for Each Locale 136
Create a Global Table Containing the Base Strings 136
Using the Localization Table 137
Adding New Locales 137
Handling Partial Translations 138
Introducing Frames, Widget Scripts, and Events 138
Frames, FontStrings, and Textures 138
Displaying Text with FontStrings 139
Showing Graphics and Colors with Textures 139
Anchoring Objects On-Screen 139
Responding to Interaction with Widget Scripts 139
Responding to Game Events 139
Loading of an Addon 141
Summary 142
Chapter 9 Working with Frames, Widgets, and Other Graphical
Elements 143
Introducing BagBuddy 143
Creating an Addon Skeleton 144
Creating a Frame 144
Parenting 145
Contents xix
Giving Objects Sizes 146
Absolute Dimensions 146
Relative Dimensions 146
Anchoring Objects 147
Sticky Anchors 148
SetAllPoints 148
Anchor Examples 148
Using Lua to Create Frames 149
Adding Layers of Textures and Font Strings 150
Layering Frames and Graphics 150
Frame Strata 150
Frame Levels 151
Graphical Layers 152
BagBuddy Frame Design 153
Finding Graphics 155
TexBrowser AddOn 155
ArtBrowser on Wowprogramming.com 155
Adding Textures 155
Defining BagBuddy’s Background Textures 157
Coloring Textures 158
Using Solid Colors 158
Creating a Gradient 159
Adding the Portrait Texture 160
Creating Textures in Lua 162
Creating Text using FontStrings 164
Further Customization 165
Using Font Definitions 165
Creating FontStrings in Lua 166
Understanding Object Visibility 166
Finding Existing Frames 167
Summary 167
The Code 168
Chapter 10 Saving Time with Frame Templates 171
Understanding Templates 171
Advantages of Using Templates 173
Naming Elements Using $parent 173
Setting Keys Using the parentKey Attribute 174
Creating a Template for BagBuddy’s Item Buttons 174
Setting Button Textures 175
Creating New Frames with Your Template 176
Exploring Font Definitions 177
Altering a Font Definition 178
xx Contents
Investigating UIPanelTemplates 179
UIPanelButtonTemplate 180
UIPanelCloseButton 180
UIPanelScrollBarTemplate 181
InputBoxTemplate 181
UICheckButtonTemplate 182
TabButtonTemplate 183
UIRadioButtonTemplate 183
Summary 183
The Code 184
Chapter 11 Exploring the World of Warcraft API 187
Understanding the WoW API 187
Normal APIs 188
Library-like APIs 188
FrameXML Functions 189
Protected Functions 189
Unit Functions Up Close 190
Querying Item Information for BagBuddy 193
Scanning Bags with the Container API 193
Querying Detailed Item Information 194
Item Identifiers 195
Using the Item API 197
Writing a Bag Scanner 198
Sorting the Player’s Inventory 199
Displaying the Inventory 199
Testing the Update Function 200
Finding the Right API Functions 201
Exploring the API Categories 201
Examining the FrameXML Code 202
Looking at Another Addon 203
Asking for Help! 203
Summary 203
The Code 204
Chapter 12 Interacting with Widgets 207
Making BagBuddy’s Buttons Interactive 207
Setting Frame Scripts via XML 208
Using the function Attribute 209
Setting Frame Scripts Using Lua 209
Showing Item Tooltips Using OnEnter and OnLeave 210
Adding Clickable Buttons to BagBuddy 212
Introducing the OnClick Handler 212
Contents xxi
Creating a Close Button Using Templates 213
Creating Clickable Filter Buttons 214
Creating the Filter Buttons Dynamically 216
Adding Custom Tooltips 217
Making the Filter Buttons Clickable 217
Updating the Results 218
Navigating Multiple Pages 219
Adding XML Definitions for Buttons and Status Text 220
Writing OnClick Handlers for Navigation Buttons 221
Altering the Update Function for Pages 221
Enabling and Disabling Navigation Buttons 222
Creating and Updating Status Text 223
Final Changes to Support Navigation 224
Adding a Name Filter to BagBuddy 224
Creating an EditBox 225
Filtering by Name 226
Exploring Widget Types 227
Button 227
CheckButton 228
ColorSelect 228
EditBox 229
GameTooltip 229
MessageFrame 229
Minimap 229
Model 230
ScrollingMessageFrame 231
ScrollFrame 231
SimpleHTML 231
Slider 232
StatusBar 232
Summary 233
The Code 233
Chapter 13 Responding to Game Events 243
Understanding Events 243
Registering for Events 244
Responding to Events with OnEvent 244
Query Events 246
Tracking Changes to Inventory for BagBuddy 246
Examining the BAG_UPDATE Event 246
Tracking New Inventory Items 246
Writing a New Sorting Function 248
Altering BagBuddy_Update 248
xxii Contents
Adding an OnEvent Handler 249
Cleaning Up 250
Adding a Slash Command 251
Storing Data with SavedVariables 251
Registering a New Saved Variable 252
Saved Variables and ADDON_LOADED 252
Using Items from BagBuddy 253
Finding the Right Event Using /eventtrace 254
Summary 255
The Code 255
Chapter 14 Tracking Damage with CombatTracker 267
Defining Specifications 267
CombatTracker User Experience 267
Finding the Right Game Events 268
PLAYER_REGEN_DISABLED 268
PLAYER_REGEN_ENABLED 268
UNIT_COMBAT 269
Creating the Addon’s Skeleton 269
Defining CombatTracker’s XML Frame 270
Defining a Backdrop 271
Adding a Font String 272
Testing CombatTrackerFrame 272
Adding Script Handlers to CombatTrackerFrame 273
Adding Functions to CombatTracker.lua 275
CombatTracker_OnLoad(frame) 275
CombatTracker_OnEvent 276
PLAYER_REGEN_ENABLED 276
PLAYER_REGEN_DISABLED 277
UNIT_COMBAT 277
CombatTracker_UpdateText() 277
CombatTracker_ReportDPS() 278
Testing CombatTracker 278
Frame Dragging 279
Right-Click Reporting: Part I 279
Testing Combat Tracking 280
Right-Click Reporting: Part II 280
Summary 281
Part III Advanced Addon Techniques 283
Chapter 15 Taking Action with Secure Templates 285
Why Are Secure Templates Necessary? 285
Protected Frames 286
Controlling Secure Frames Using Attributes 288
Contents xxiii
Using Secure Templates 288
Defining Behaviors for Action Buttons 289
Casting a Spell 289
Looking Under the Hood 290
Specifying Units to Affect 291
Other Types and Their Uses 291
Making Simple Choices 296
Working with Modified Attributes 296
Delegating Attribute Responsibility 298
Choosing an Action by Hostility 298
Applying Action Buttons in Practice 299
Modifying an Existing Frame 299
A Complex Action Button 300
Understanding Taint and Working Safely Around Secure
Code 302
Enabling Taint Logging 303
Execution Taint 304
Variable Taint 305
Creeping Taint 307
Summary 308
Chapter 16 Binding Keys and Clicks to Addon Code 309
Defining Bindings in XML 310
Creating Your Own Binding Actions 312
Binding Keys to Actions 314
Building a Simple Binding UI 315
Defining Basic Behaviors 318
Using SetBinding() 321
Working with Existing Bindings 324
Displaying an Action’s Bindings 325
Understanding Binding Storage 326
Binding Keys to Secure Actions 327
Working with Click Bindings 328
Creating Secure Bindings in XML 329
Summary 329
The Code 330
BindingTest 330
ClickBindingTest 334
Chapter 17 Creating Slash Commands 337
Creating Basic Slash Commands 337
Tokenizing Strings 339
Tokenizing with Patterns 341
Setting Up the Patterns 341
xxiv Contents
Preparing for the Tokenization 342
Parsing the Formula 343
Using a Command Table 345
Summary 347
The Code 347
SlashCalc 347
Chapter 18 Responding to Graphic Updates with OnUpdate 351
Understanding Graphic Updates 351
Delaying Code Using OnUpdate 352
Grouping Events to Avoid Over-Processing 354
Grouping Multiple Events 355
Repeating Code with OnUpdate 356
Considering Performance with OnUpdate Scripts 357
Summary 357
Chapter 19 Altering Existing Behavior with Function Hooking 359
What Is Function Hooking? 359
Modifying Return Values 360
Using a Variable Argument Function 361
Using Utility Functions capture() and release() 361
Hooking Widget Scripts 362
Hooking a Function Securely 364
Hooking Scripts Securely 365
Deciding When to Hook 365
Understanding the Hook Chain 365
You Can’t Rely on Order 366
There Is No ‘‘Unhook’’ 366
Hooking Hits Performance 366
Finding Alternatives 367
Designing an Addon: MapZoomOut 367
Creating a Timer Frame 368
Initial Setup 368
Create the Function Hook 369
Writing the Timer Code 369
Final Setup 370
Testing MapZoomOut 370
Summary 370
The Code 371
MapZoomOut 371
Chapter 20 Creating Custom Graphics 373
Common Rules for Creating Graphics 373
The GIMP 374
Contents xxv
Create a New Image 374
Adding Graphical Components 375
Saving Textures 376
Adobe Photoshop 376
Create a New Image 376
Adding Graphical Components 377
Creating an Alpha Channel 377
Saving an Image 378
Paint Shop Pro 379
Creating a New Image 380
Adding Graphical Components 380
Creating an Alpha Channel 381
Saving an Image 382
Testing Your Texture 383
No Button Appears 384
A Green Box Appears 384
XML Texture Definition 384
Lua Texture Definition 385
Summary 385
Chapter 21 Responding to the Combat Log and Threat Information 387
Understanding the Combat Log 387
Event Arguments 387
Combat Sub-Events 388
Combat Event Prefix 389
Bit Fields and Spell Schools 389
Combat Event Suffix 390
Spell-Only Suffixes 393
Special Combat Events 395
Unit GUIDs 396
Format of GUIDs 397
Unit Flags 398
COMBATLOG_OBJECT_TYPE_MASK 398
COMBATLOG_OBJECT_CONTROL_MASK 398
COMBATLOG_OBJECT_REACTION_MASK 399
COMBATLOG_OBJECT_AFFILIATION_MASK 399
COMBATLOG_OBJECT_SPECIAL_MASK 399
Using CombatLog_Object_IsA 400
Writing CombatStatus 401
Creating the Basic Addon Structure 401
Initializing CombatStatus 402
Updating Pet Mappings 405
Storing Damage and Healing Information 405
Taking ‘‘Snapshots’’ of Damage and Healing 407
xxvi Contents
Writing an OnUpdate Function 408
Responding to Events 408
COMBAT_LOG_EVENT_UNFILTERED 409
PARTY_MEMBERS_CHANGED 409
UNIT_PET 409
PLAYER_REGEN_DISABLED 409
PLAYER_REGEN_ENABLED 410
Creating the Frame Display 410
Updating the Frame Display 410
Future Additions 412
Summary 412
Chapter 22 Creating Scroll Frames 413
Using Scroll Frames 414
Adding a Scroll Child 415
Manipulating a ScrollFrame 416
Adding Scroll Bars 417
Creating Faux Scroll Frames 419
Adding Scroll Bars 422
Scrolling with the Mouse Wheel 423
Problems with Slider Precision 423
Summary 424
The Code 424
ScrollFrameTest 424
MacroIconTest 426
Chapter 23 Creating Dropdown Menus 431
Creating a Basic Dropdown 431
Adding a Toggle Button 432
Creating a Dropdown Frame 433
Initializing the Dropdown 433
Adding Buttons to the Dropdown 433
Calling UIDropDownMenu_Initialize() 434
Toggling the Dropdown Menu 434
Testing the Dropdown 435
Creating Multilevel Dropdowns 436
Adding Functionality to Dropdowns 437
Customizing Text Elements 438
Function Menu Items 440
CheckButton Menu Items 440
ColorPicker Menu Items 441
Using Dropdowns for Selection 443
Automating Menu Creation with EasyMenu 445
Creating Dynamic Menus 447
Summary 449
Contents xxvii
Chapter 24 Scanning and Constructing Tooltips 451
Understanding the Tooltip System 451
Different Types of Tooltips 452
Contextual Tooltips 452
Static Tooltips 453
Tooltip Contents 453
Custom Text in a Tooltip 453
Game Element Tooltips 455
Adding Information to the Tooltip 458
Loading the Tooltip with Item Information 458
Getting Information from Tooltips 460
Accessing Individual Tooltip Lines 460
Checking Soulbound Status 461
Using Global Strings for Localization 461
Replacing a Script Instead of Hooking a Script 461
Summary 462
Chapter 25 Taking Protected Action in Combat 463
Snippets: The Basis of Secure Action 463
How Can Addon Code Be Secure? 463
Writing a Snippet 464
Secure Handler Frames 464
Handler Template Reference 466
Integrating a Click Handler with a Secure Action Button 468
Preserving State and Controlling Information 473
Private Global Environments 474
Secure API Functions 475
The control Object 476
Frame Handles 477
Allowed Actions 479
Additional or Changed Actions 479
Wrapping Frame Scripts 482
A Simple Click Wrapper 483
Using a Post-Hook 484
Script Wrapper Reference 485
Triggered Changes 486
State Drivers 486
State Responders 487
Responding to Show/Hide 487
Responding to Attribute and State Changes 488
State Conditionals 490
Target Specifiers and Unit Conditions 491
State Variables 492
Unit Conditions 492
General Conditions 493
xxviii Contents
Summary 496
The Code 496
BlessedMenus 496
Chapter 26 Creating Unit Frames with Group Templates 501
Configuring a SecureGroupHeader 501
Configuration Options 502
Initial Configuration Function 505
Creating SquareUnitFrames 506
Constructing the Template 506
Creating a Header Template 508
Setting Name and Status Bars 509
Nudging Frame Levels 511
Responding to Events and Clicks 511
Targeting the Unit on Left-Click 511
Moving the Header 512
Health Update Events 513
Power Update Events 514
Responding to Name Changes 516
Enhancing SquareUnitFrames 516
Highlighting Units on Mouseover 516
Showing the Targeted Unit 517
Displaying Threat Levels 518
Showing Dead Players 519
Displaying Unit Names 521
Adding Pets to SquareUnitFrames 523
Creating a SecureGroupPetHeaderTemplate 526
Summary 526
The Code 526
SquareUnitFrames 526
Part IV Reference 537
Chapter 27 API Reference 539
API Reference Conventions 539
Function Signatures 539
Optional Arguments 540
Argument Choices 540
Argument and Return Listings 540
Common API Flags 541
API Meta-Types 542
1nil 542
actionID 542
ah-list-type 543
Contents xxix
anchorPoint 543
arenaTeamID 543
auraFilter 543
backdrop 544
bitfield 544
binding 545
chatMsgType 545
colorString 545
containerID 546
containerSlotID 546
frameStrata 546
glyphIndex 547
GUID (Globally Unique IDentifier) 547
Players 547
NPCs 547
Pets 548
Vehicles 548
GUID Example 548
Hyperlink 549
player 549
playerGM 549
glyph 549
spell 550
enchant 550
quest 550
talent 550
achievement 551
trade 551
item 552
inventoryID 552
itemID 553
itemLocation 553
itemQuality 553
itemString 554
justifyH 554
justifyV 554
layer 554
macroID 554
powerType 554
rollID 555
spellbookID 555
spellID 555
standingID 555
unitID 555
API Reference 556
xxx Contents
Chapter 28 API Categories 1025
Achievement Functions 1025
Action Functions 1027
ActionBar Functions 1028
Addon-related Functions 1028
Arena Functions 1029
Auction Functions 1030
Bank Functions 1031
Barbershop Functions 1032
Battlefield Functions 1032
Blizzard Internal Functions 1035
Buff Functions 1035
CVar Functions 1035
Calendar Functions 1036
Camera Functions 1040
Channel Functions 1041
Chat Functions 1043
Class Resource Functions 1045
Client Control and Information Functions 1045
Combat Functions 1046
CombatLog Functions 1046
Companion Functions 1047
Complaint Functions 1047
Container Functions 1047
Currency Functions 1048
Cursor Functions 1049
Debugging and Profiling Functions 1051
Duel Functions 1052
Equipment Manager Functions 1052
Faction Functions 1053
GM Survey Functions 1054
GM Ticket Functions 1054
Glyph Functions 1054
Guild Bank Functions 1055
Guild Functions 1056
Hyperlink Functions 1059
In-game Movie Playback Functions 1060
Inspect Functions 1060
Instance Functions 1061
Inventory Functions 1061
Item Text Functions 1063
Item Functions 1063
Contents xxxi
Keybind Functions 1065
Keyboard Functions 1065
Knowledge-base Functions 1066
Limited Play Time Functions 1067
Locale-specific Functions 1067
Looking For Group Functions 1068
Loot Functions 1069
Lua Library Functions 1070
Mac Client Functions 1072
Macro Functions 1073
Mail Functions 1074
Map Functions 1075
Merchant Functions 1076
Modified Click Functions 1078
Money Functions 1078
Movement Functions 1079
Multi-cast Action 1080
NPC ‘‘Gossip’’ Dialog Functions 1080
Objectives Tracking Functions 1081
Party Functions 1082
Pet Stable Functions 1083
Pet Functions 1083
Petition Functions 1085
Player Information Functions 1085
PvP Functions 1088
Quest Functions 1089
Raid Functions 1094
Recruit-a-friend Functions 1095
Secure Execution Utility Functions 1095
Skill Functions 1096
Social Functions 1096
Socketing Functions 1097
Sound Functions 1098
Spell Functions 1099
Stance/Shapeshift Functions 1101
Stat Information Functions 1101
Summoning Functions 1103
Talent Functions 1103
Targeting Functions 1104
Taxi/Flight Functions 1105
Threat Functions 1105
Tracking Functions 1106
Trade Functions 1106
xxxii Contents
Trade Skill Functions 1107
Trainer Functions 1108
Tutorial Functions 1110
UI/Visual Functions 1110
Unit Functions 1110
Utility Functions 1113
Vehicle Functions 1115
Video Functions 1116
Voice Functions 1117
Zone Information Functions 1119
Chapter 29 Widget Reference 1121
Widget Types 1121
UIObject 1121
ParentedObject 1122
ScriptObject 1122
Region 1124
VisibleRegion 1129
LayeredRegion 1130
FontInstance 1131
FontString 1135
Texture 1138
Frame 1145
Button 1164
CheckButton 1170
ColorSelect 1172
Cooldown 1175
GameTooltip 1176
Minimap 1192
Model 1195
PlayerModel 1201
DressUpModel 1202
TabardModel 1202
MovieFrame 1204
ScrollFrame 1206
SimpleHTML 1208
Slider 1215
StatusBar 1219
Font 1221
MessageFrame 1222
ScrollingMessageFrame 1225
EditBox 1231
AnimationGroup 1238
Contents xxxiii
Animation 1243
Path 1248
ControlPoint 1250
Rotation 1251
Scale 1252
Translation 1253
Alpha 1254
Widget Scripts 1255
Chapter 30 Events Reference 1277
Part V Appendixes 1303
Appendix A Best Practices 1305
General Programming 1305
Use Meaningful Variable Names 1306
Variable Naming Exceptions 1307
Use Named Constants Instead of Literals 1307
Organize for Easier Maintenance 1308
Rework Repetitive Code 1308
Break Apart Long Functions 1309
Use Consistent Programming Style 1309
Lua Tips 1310
Use Local Variables 1310
Minimize Unnecessary Garbage 1311
How to Reduce Garbage 1312
Recyclable Objects 1317
Recycle Tables 1318
Other Fine-tuning Optimizations 1319
Check Expected Conditions First 1319
Exploit Shortcut Evaluation 1320
Use Tables as a Logic Structure 1321
Cache Frequently Accessed Values 1322
The WoW Environment 1323
Use What You’re Given 1323
Localize with Global Strings 1323
Avoid Deprecated Systems 1324
Global Widget Handler Arguments 1324
bag and slot Attributes on item Type Action Buttons 1325
Avoiding Common Mistakes 1325
Adding Files While WoW Is Running 1325
Entering |into the Chat Edit Box 1326
‘‘Missing’’ Frames 1326
Ignoring Logs\FrameXML.log 1326
Not Checking API Returns 1326
xxxiv Contents
Requesting Data Before PLAYER_LOGIN 1327
Conflicting or Existing Anchor Points 1327
Appendix B Utilizing Addon Libraries 1329
What Is an Addon Library? 1329
How Do Libraries Work? 1330
Standalone Libraries 1330
Advantages 1331
Disadvantages 1331
Embedded Libraries 1332
Embedded Library Load Process 1332
Manually Versioning an Embedded Library 1333
Versioning Using LibStub 1334
Using a Library 1335
Ace3 1335
Portfolio 1336
Dongle 1336
PeriodicTable 1336
BossIDs 1336
LibHealComm 1336
LibSharedMedia 1336
Other Library Resources 1337
Appendix C Tracking History Using Version Control Systems 1339
Subversion 1339
Terminology 1340
Layout of a Repository 1340
Obtaining Subversion 1341
Command Primer 1341
svn checkout <url>[path] 1341
svn update [path] 1342
svn add <path>1342
svn commit [path] 1342
svn status 1342
svn log [path] 1343
svn diff [path] 1343
Creating a Local Repository 1343
Git and Mercurial 1344
Terminology 1344
Obtaining Git 1345
Obtaining Mercurial (hg) 1345
Typical Usage 1345
Git 1345
Mercurial 1347
Contents xxxv
Appendix D Addon Author Resources 1349
Community Websites 1349
World of Warcraft Forums 1349
WowProgramming Forums 1350
WoWInterface Forums 1350
WowAce Forums 1350
Curse Forums 1350
Elitist Jerks 1350
IncGamers UI Customization Forums 1351
Internet Relay Chat (IRC) 1351
#wowuidev on irc.freenode.net 1351
#wowace on irc.freenode.net 1351
#wowprogramming on irc.freenode.net 1351
Distributing and Supporting Your Addon 1352
WoW-Specific Hosting 1352
WoWInterface 1352
CurseForge and WowAce 1353
IncGamers 1353
Other Hosting Solutions 1353
Google Code 1353
Sourceforge 1354
Personal Web Hosting 1355
Index 1357
Introduction
Since World of Warcraft (WoW) was released on November 23, 2004, it has
been one of the most popular video games ever created. The game currently
boasts more than eleven million subscribers; it seems that everyone knows
someone who plays. World of Warcraft is an extremely immersive environment
that allows you to customize your character, explore new worlds, and group
with friends without requiring an enormous time commitment. Some players
spend four to six hours a night raiding with their guilds trying to defeat the
latest and greatest monster. Others prefer player-to-player combat, spending
time in the Arena or Battlegrounds trying to improve their standing. Some
players just enjoy playing the game with a group of friends when they have
spare time. World of Warcraft has something to offer each of these players,
and that’s probably one of the primary reasons for its success.
One aspect of the game that reaches each of these play styles is user
interface customization in the form of addons. For those players who are
technically inclined or simply can’t accept things being anything less than
perfect, Blizzard has opened up its user interface to allow players to customize
and change its overall functionality. Addons can be as simple as changing the
colors of health bars or adding a new slash command to do random emotes, or
as complicated as providing complex statistical analysis of a server’s economy.
Beyond opening up this world of customization, Blizzard continues to provide
enhancements and support for the user interface community in a way that no
other game developer has done.
The user interface community has grown immensely over the past few
years, and shows no signs of stopping. This book was written to give the
reader the tools necessary to create custom modifications to the World of War-
craft user interface, including an introduction to the languages, terminology,
and structure of addon creation. There are thousands of addons out there
xxxvii
xxxviii Introduction
waiting to be written, and this book provides you with the skills necessary to
realize them.
Who This Book Is For
This book is designed to be useful to novice addon users who want to learn
how to tweak existing addons, to budding addon authors looking to add more
exciting features to their repertoire, and to advanced addon developers as a
reference to the extremely complex WoW UI system. The only assumptions
made throughout the book are that you are familiar with World of Warcraft
and have an interest in programming. Readers who have had exposure to
programming languages in any form will find many of the concepts presented
to be familiar.
The reader with little to no prior programming experience should initially
focus on the first section of the book, which teaches Lua, the programming
language that is used to write addons. Although readers with no programming
experience will learn enough to create and modify addons, they may want to
pursue more general programming lessons from another source to supplement
the material presented.
For readers with prior programming experience, the first few chapters
will be very easy. The examples can be used to pick up the basic rules of
the Lua programming language rather quickly. If you are already familiar
with high-level scripting languages such as Python or JavaScript, you can
easily skim the first few chapters and move right into the second section,
which covers the basics of addon creation itself. These chapters detail how
the WoW addon system works for the author, and lead you through writing
your first addon.
Addon authors may want to skip directly to the third section of the book. Its
chapters introduce specific concepts and walk through the creation of working
example addons that use the concepts. Some of the more obscure difficult
systems (such as secure snippets, dropdown menus, and state headers) are
explored in depth.
In addition, the fourth section of the book contains an extremely compre-
hensive reference to the WoW API, including events and widgets.
How This Book Is Organized
This book is divided into four parts that introduce increasingly complex topics.
Part I is an introduction to Lua and XML, bringing you up to speed with the
languages needed to create addons.
Introduction xxxix
Part II discusses the way addons are built and the basics behind the frame
system in World of Warcraft. In this part you create your first addon and
become familiar with the WoW API.
Part III of the book guides you through some of the more advanced topics
by creating a number of addons from start to finish.
Finally, Part IV is a comprehensive reference to the entire API, including
functions, widgets, events, and secure templates.
What’s on the Website
Every few months, Blizzard releases a new patch for World of Warcraft that
may introduce new content, fix existing bugs, or even drastically change game
mechanics. As a result, the material covered in this book will change from time
to time. To help combat this problem, the authors have created a companion
website for the book at http://wowprogramming.com. While we do not expect
sweeping changes to the core concepts, the details of any specific changes will
be listed on the website, including information about how those changes affect
the material in this book. Besides serving as a glorified errata repository, the
website also has online versions of all the references included in the book.
From Here
The World of Warcraft user interface community is a very exciting place
with endless possibilities for customization and realization of ideas. World of
Warcraft is a fun game in its own right; the capability to use it as a development
platform for addons that can help users and enhance their game experience is
an extra bonus that each of us can enjoy. So Enjoy!
Part
I
Learning to Program
In This Part
Chapter 1: Programming for World of Warcraft
Chapter 2: Exploring Lua Basics
Chapter 3: Basic Functions and Control Structures
Chapter 4: Working with Tables
Chapter 5: Advanced Functions and Control Structures
Chapter 6: Using the Lua Standard Libraries
Chapter 7: Learning XML
CHAPTER
1
Programming for World
of Warcraft
World of Warcraft (WoW) was released Nov. 23, 2004, and very quickly became
the model for Massively Multiplayer Online Role Playing Games (MMORPG).
Providing an intuitive user interface and a low barrier to success the game
is currently played by more than 11 million users, including their friends,
co-workers, and families. WoW has something enjoyable for those players
who spend six hours a night raiding with their guilds, the cubicle warriors
who play for half an hour a day on their lunch breaks, and a large range of
individuals in between.
Beyond killing monsters and questing for glory, there is another side to
World of Warcraft, a game within a game. Blizzard has provided an extremely
powerful system for creating third-party addons and writing macros, and
users have been taking advantage of the open system since the beta test for
the game. This book is designed to introduce you to the world of customizing
World of Warcraft and show you how to create custom addons.
Customizing the User Interface
The World of Warcraft game client consists of two major parts: the game world
and the user interface. The game world is the three-dimensional space in which
your character resides. This includes the buildings and terrain, other players
and enemies, and interactive objects such as herbs, mining veins, mailboxes,
and signposts. The game world also includes some nonthree-dimensional
objects, namely the character names and titles, and the numbers that show the
damage your character has done. These elements are not accessible through
the scripting interface and cannot be modified.
3
4PartILearning to Program
The user interface comprises the other elements in the client, including
the action buttons, unit frames, maps, and options windows. Addons can be
written to add or modify existing elements to add functionality or to show
information in a different way.
What Is an Addon?
An addon is a collection of files inside a named directory within the World of
Warcraft directory. These files are loaded by the game’s scripting system and
executed within the client to make some modification to the user interface.
This definition of addons does not include any third-party executables that
are run outside the game (those sorts of programs are normally prohibited by
WoW’s terms of service).
The average addon consists of individual components that work together to
create a final product, possibly including:
A table of contents file that identifies the addon and the files to be loaded
Media files, such as graphics and sounds
Lua scripts that define the behavior of the addon
XML files that define the visual elements of the addon
The first part of this book is designed to introduce you to the Lua program-
ming language and the XML markup that is specific to World of Warcraft.
These skills are an important part of writing addons effectively. If you are
already proficient in Lua and XML, you can skip ahead to Part II of the
book, which covers the use of the World of Warcraft API in creating addons;
however, you will likely find the material in Part I worthwhile.
What Can Addons Do?
Addons typically fall into one or more of the following categories:
Displaying additional information, such as the sale price of quest rewards
(Figure 1-1), or approximately how many more of a given spell you can
cast without running out of power (Figure 1-2).
Changing the display of interface elements, such as the combat text
information (Figure 1-3), or making the auction house interface easier to
navigate (Figure 1-4).
Providing new ways for the player to take action (targeting units, casting
spells) within the game, such as replacement unit frames (Figure 1-5) or
alternate action buttons (Figure 1-6).
Chapter 1 Programming for World of Warcraft 5
Figure 1-1: Valuation showing sell price for items
Figure 1-2: Dr. Damage displaying number of possible casts
Figure 1-3: MikScrollingBattleText displaying combat information
6PartILearning to Program
Figure 1-4: Auctioneer displaying auction listings in a compact form
Figure 1-5: Grid unit frames showing the status of a raid
Figure 1-6: Bartender4 with ButtonFacade_Serenity providing alternate action buttons
Prior to the release of the Burning Crusade expansion pack to World of
Warcraft, there were several addons that Blizzard deemed against the spirit
and intention of the game. These addons were later disabled and changes were
Chapter 1 Programming for World of Warcraft 7
made to the scripting system to prevent their use. As a result the following
actions are unavailable to addons:
Automatic character movement
Automatic target selection
Automatic selection and use of spells or items
Real-time communication with external programs
In the past, Blizzard has been asked about the limits of the scripting/macro
system. Its response has been that it is interested in ‘‘smart players,’’ not ‘‘smart
buttons.’’ In other words, addons and macros can work to display information
to the users or allow them to access functionality in an easier way, but should
not be used to make automatic decisions.
In addition, addons are forbidden from doing anything that would otherwise
be against the World of Warcraft ‘‘Terms of Use,’’ which you can find at
http://worldofwarcraft.com/legal/termsofuse.html.
Exploring Your AddOns Directory
As mentioned previously, all addons must exist within a subdirectory under
your World of Warcraft directory. Depending on what operating system you
are using and how you have installed the game, this directory may exist in
one of a few places (see Table 1-1). If you happen to be running Windows
Vista, the location of your installation will depend on how the computer has
been configured and where the game was installed. During the installation of
Wrath of the Lich King or patch 3.0.2 you should have been asked to move the
game to option #3. If you agreed to this change, you may have two versions of
World of Warcraft, with the old one not being used any more.
Table 1-1: Default World of Warcraft Installation Directory
OPERATING SYSTEM DEFAULT INSTALLATION DIRECTORY
Microsoft Windows 98, 2000,
or XP
C:\Program Files\World of Warcraft
Microsoft Windows Vista
(option #1)
C:\Program Files\World of Warcraft
Microsoft Windows Vista
(option #2)
C:\Users\<username>\AppData\Local\
VirtualStore\Program Files\World of
Warcraft
Microsoft Windows Vista
(option #3)
C:\Users\Public\Games\World of
Warcraft
Mac OS X /Applications/World of Warcraft
8PartILearning to Program
If you have launched World of Warcraft previously, there should be an
Interface directory within and an AddOns directory below that. This is where
all addons are stored.
Blizzard Addons
Much of the functionality in the default user interface is implemented via mod-
ular addons that are loaded only when needed by the user. When the player
visits an auctioneer, for instance, the game loads the Blizzard_AuctionUI
addon.
Having the addons in separate load-on-demand modules allows addon
authors to easily override the default functionality (such as replacing the
auction house interface rather than just changing it). In addition, the modularity
speeds up load times when starting the game. Table 1-2 describes the existing
Blizzard addons.
Table 1-2: Blizzard Load-on-Demand Addons
ADDON NAME PURPOSE
Blizzard_AchievementUI Explore the achievements your character can
complete and those he has already
completed.
Blizzard_ArenaUI Display unit frames for enemy units in arena
PVP.
Blizzard_AuctionUI Search for items available for sale, as well as
posting new items up for auction.
Blizzard_BarbershopUI Customize the facial features and hair
style/color for your character.
Blizzard_BattlefieldMinimap Display a smaller version of the world map,
including the PVP objectives.
Blizzard_BindingUI Customize the keyboard bindings made
available by the default and custom
interfaces.
Blizzard_Calendar Display a calendar that shows the various
scheduled game events and allows players
to create their own events.
Blizzard_CombatLog Present combat information in a linear
combat log that can be filtered and colored
via options.
Continued
Chapter 1 Programming for World of Warcraft 9
Table 1-2: (continued)
ADDON NAME PURPOSE
Blizzard_CombatText Show various combat events in moving text
in the user interface, customizable via the
options screens.
Blizzard_DebugTools Provide slash commands and utility functions
that are useful to addon developers.
Blizzard_GMChatUI Provide a chat window for communication
with game masters.
Blizzard_GMSurveyUI Allow the user to fill out a survey that has
been sent by Blizzard following a GM
interaction.
Blizzard_GlyphUI Inscribe glyphs into your spellbook in order
to customize your spells.
Blizzard_GuildBankUI Add and remove items and gold from your
guild’s bank.
Blizzard_InspectUI Inspect another player to view his
equipment, combat stats, and talents.
Blizzard_ItemSocketingUI Socket gems into an item.
Blizzard_MacroUI Edit global and character-specific macros.
Blizzard_RaidUI Display unit frames for the members in your
raid.
Blizzard_TalentUI Assign talent points and explore the various
talent trees.
Blizzard_TimeManager Show a clock on the minimap and provide a
simple in-game timer.
Blizzard_TokenUI View the various currency tokens that your
character has earned.
Blizzard_TradeSkillUI Explore the various recipes that are
associated with a given tradeskill.
Blizzard_TrainerUI Purchase skills available from a trainer.
Each of these directories contains a single file that has the addon’s name
and a .pub extension. As far as we can tell, this is some sort of signature
used by the game to verify the authenticity of the addon. Addons that are
written by Blizzard are given a special ‘‘secure’’ flag that allows them to take
10 Part I Learning to Program
protected actions, something that is covered in Chapter 8. The code for the
addons is actually stored in the data files for the game and can’t be directly
replaced.
Custom Addons
If you have downloaded any custom addons they will sit alongside the
Blizzard addons in your Interface\AddOns directory inside subdirectories.
Unlike the official addons, these addon directories actually contain the files
that are necessary to load and run the addon. The organization and contents
of these files varies depending on the addon. Each author has his or her own
preferences and style and these differences are reflected in the way the addon
is packaged and the way the code is written. Although we provide some
recommendations for writing and packaging your addons, you are free to
develop a style that works best for you.
Creating Your First Addon: HeyThere
Before you delve into Lua and XML, take a look at a very simple addon
example so you’ll have an idea of how the system works. To complete the
example you need to know how to create a new directory on your computer.
You also need to be familiar with a text editor that saves files without special
formatting. On Windows, for example, you could use Notepad to edit files; on
Mac OS X, the built-in Text Editor program is sufficient.
Creating Files and Directories
First create a new directory that will contain the addon. Navigate to your
Interface\AddOns directory and create a new directory inside called HeyThere.
Open your text editor and type the following into the file:
## Interface: 30300
## Title: Hey There!
## Notes: Provides slash commands to greet other players
HeyThere.lua
Save this file in the new directory as HeyThere.toc. Open a new file in the
editor and add the following:
SLASH_HEYTHERE1 = “/hey“
SLASH_HEYTHERE2 = “/heythere“
SlashCmdList[“HEYTHERE“] = function(self, txt)
if UnitExists(“target“) then
Chapter 1 Programming for World of Warcraft 11
SendChatMessage(“Hello “ .. UnitName(“target“), “SAY“)
else
SendChatMessage(“Hey there everybody!“)
end
end
Save this file as HeyThere.lua in the same directory and close the text editor.
Don’t worry right now about what any of this code does; it’s just an example
addon to get you familiar with creating files and directories. You’ll learn what
the code does later in the book.
Loading and Testing the Addon
If you have World of Warcraft open, you must close it so it can recognize the
new addon. Once you’ve re-opened the game client, log in to your account and
stop at the character selection screen. In the bottom left of the screen should
be a button named AddOns. Click it and a window similar to one shown in
Figure 1-7 opens. The window shows that WoW recognizes your addon and
willtrytoloaditifitisenabled.
TIP You may find it useful to create a character on a server that is different from
your main server for addon development. This allows you to easily change which
addons are enabled and disabled without affecting the characters with which you
normally play.
Figure 1-7: Addon selection screen showing your new addon
Ensure that the addon is enabled by checking the box to the left of the
addon name. Click Okay to exit the addon selection screen and enter the game.
12 Part I Learning to Program
This addon adds two new slash commands that allow you to greet people in
the world. You can type either /heythere or simply /hey and depending on
whether you have something targeted your character will display one of two
messages (see Figure 1-8).
Figure 1-8: HeyThere greeting with (left) and without (right) a target
If for some reason you do not see the addon in the addon selection list,
ensure that you’ve created the files and directories correctly. The layout should
be as follows:
Interface\AddOns\HeyThere
Interface\AddOns\HeyThere\HeyThere.toc
Interface\AddOns\HeyThere\HeyThere.lua
If you get an error or have any other issues, double-check that you’ve typed
everything correctly in each of the files. Alternatively, download the addon
from this chapter’s section of the website at http://wowprogramming.com/
chapters/01 and compare it to the version you have created.
Summary
This chapter introduced you to the addon system for World of Warcraft. The
specific limitations and capabilities of the system were listed, along with a
description of the addons that Blizzard has included with the game. You
createdyourfirstaddonandtestedin-gametoensureitworkedcorrectly.
Chapter 2 introduces you to the basics of the Lua programming language,
used extensively when creating addons.
CHAPTER
2
Exploring Lua Basics
Lua is a powerful, lightweight, embedded scripting language that is used
in several large software projects, including WoW. Lua is a fairly small
programming language, and you may find some similarities to other languages
you already know. Lua is most often compared to Python because both are
relatively easy for a non-programmer to use when compared to languages
such as C or Java.
This chapter serves as a general introduction to the Lua programming
language. If you have prior experience with Lua or have extensive experience
using other programming languages, you may want to skim this chapter
and run through some of the interactive exercises. Although these examples
should be easy to understand without you needing to run them, we strongly
encourage you to download a Lua interpreter so you can run through the
examples on your own. In addition, an interpreter allows you to easily explore
the language to increase your overall understanding of concepts.
ON THE WEB
You can read more about the Lua programming language at www.lua.org.
The website contains a large amount of reference material, including an online
version of Programming in Lua, a book entirely about the Lua programming
language.
13
14 Part I Learning to Program
Downloading and Installing Lua
You have three easy ways to obtain a Lua interpreter:
1. Download WowLua, an addon the authors have written that gives you
an interactive Lua interpreter within World of Warcraft.
2. Visit the book’s website at http://wowprogramming.com/utils/weblua
to use an interactive Lua interpreter in your web browser.
3. Download a Lua interpreter to your computer, so it can be run locally
without access to the Internet or WoW.
The first option enables you to run a Lua interpreter directly within World of
Warcraft. This is useful if you want to spend your time in the game watching
things. The second allows you to run Lua without needing to download
anything, so it will work even on computers where you can’t install software.
The third option allows you to work with Lua when you’re not connected to
the Internet, which also can be useful.
Any of these options will work for the examples in the first part of this book,
so feel free to choose the ones that work best for you.
Downloading and Installing WowLua
We have created a version of the Lua interpreter that runs as an addon within
World of Warcraft. This is the simplest way to install a Lua interpreter for
anyone with experience using addons. It also has the advantage of letting you
work within the game, allowing you to test your work on-the-fly, experiment
with the default UI and other addons, and still be able to chat with your friends
and guild.
Navigate to http://wowprogramming.com/utils/wowlua-addon and click
thedownloadlinktogetthelatest version of the WowLua addon. This
downloads a .zip file to your computer. Once you save the file, you can
extract it using your favorite compression utility or by double-clicking it on
a standard Windows XP or Mac OS X machine. A single folder called WowLua
will be extracted. Place the folder in the Interface\AddOns folder underneath
your World of Warcraft installation.
You can verify that the addon is installed properly by clicking the Addons
button in the bottom-left corner of your character selection screen. You should
see the addon listed in a fashion similar to that shown in Figure 2-1.
Chapter 2 Exploring Lua Basics 15
Figure 2-1: WowLua in the addon listing
Select a character and log in to the game. Type either /lua or /wowlua into
the chat box to open the WowLua window (see Figure 2-2). You can close the
window by clicking the X button in the top-right corner, or by pressing the
Esc key.
Figure 2-2: WowLua interactive interpreter
Using Lua on the Web
For those people who don’t want to run these examples within WoW and
have access to an Internet connection, we’ve created a simple webpage that
serves as a Lua interpreter over the Web, called WebLua. Simply browse to
http://wowprogramming.com/utils/weblua to begin.
The webpage requires JavaScript to function, so ensure you have it enabled
in your web browser.
16 Part I Learning to Program
Downloading and Installing a Lua Interpreter
If you prefer to download an interpreter so you can work offline, packages are
available for both Microsoft Windows and Mac OS X.
Microsoft Windows
You can download the interpreter for Microsoft Windows at http://
wowprogramming.com/utils/lua/windows. The package doesn’t require any
installation; you can simply place it anywhere that is convenient for you.
Extract the ZIP file to a new folder and place it where you can easily find
it again.
To launch the Lua interpreter, go to the files you’ve extracted and
double-click the icon for the interpreter. This opens a window that looks
something like that shown in Figure 2-3. You can also create a shortcut to this
file from which you can launch the interpreter.
Figure 2-3: Lua running on Microsoft Windows
Mac OS X
You can find a package that can be used to install a Lua interpreter for Mac
OS X at http://wowprogramming.com/utils/lua/macosx. The download is
a standard disk image that can be mounted on your system. To mount it,
navigate to the disk image and double-click it. The disk image contains a
package (selected in Figure 2-4) that you can run to install Lua on your system.
Double-click the package to install Lua on your system.
To launch the Lua interpreter, you need to open Terminal. This is an appli-
cation normally located under Applications Utilities. A window appears,
so you can type lua and press Enter to actually open the Lua interpreter.
Figure 2-5 shows a terminal window with Lua running.
Chapter 2 Exploring Lua Basics 17
Figure 2-4: LuaforMacOSXdiskimage
Figure 2-5: Lua running on Mac OS X
Using the Lua Interpreter
When you launch your interpreter for the first time, you are greeted with
something similar to the following:
Lua 5.1.4 Copyright ©1994-2007 Lua.org, PUC-Rio
>
The first line contains the version string of the particular Lua interpreter
you are using. As long as you are using a version that begins with 5.1 you
18 Part I Learning to Program
should be okay. The second line of output is the prompt, where you can type
commands to be run.
Running Commands
The Lua interpreter is interactive, enabling you to input commands and
receive a response, like a conversation between two friends. You will receive
instant feedback with any errors in your code, allowing you to tinker with the
language to see how it works.
Type the following command at the prompt (you only need to type the part
after the >, shown in bold):
>print(“Hello Azeroth!“)
Youshouldseethefollowingoutput:
Hello Azeroth!
>
This simple command takes the text string Hello Azeroth! and sends it to
the function print(), which outputs the string to your window. You examine
the nitty-gritty details of what this actually means later in this chapter.
NOTE For the purposes of this chapter, consider a function to be a process that
you can give information, and have it complete some task. In this case, you feed a
string to the function, which prints it to the output window.
Understanding Error Messages
Inevitably, you will make a typo and get an error from Lua when running a
command. The error messages are usually human-readable and will tell you
where the problem occurred. Type the following command at the prompt
(note that you’re intentionally misspelling the word print):
>prnit(“Hello Azeroth!“)
The response, a typical error message in Lua, is similar to this:
stdin:1: attempt to call global 'prnit’ (a nil value)
stack traceback:
stdin:1: in main chunk
[C]: ?
>
The first line gives you the error message and the line number on which
the error occurred. In this case, Lua says that you tried to call a global prnit,
which is a nil value. In layman’s terms, it means you tried to call a function
that doesn’t exist.
Chapter 2 Exploring Lua Basics 19
The rest of the error message is called a stack traceback, which tells you
where the error occurred. This will be useful when you begin calling functions
from other functions.
Using History to Make Changes
Depending on the Lua interpreter you are using, you may be able to view
the recent command-line history (the last few commands you’ve given the
interpreter) by pressing the Up and Down arrow keys. Test this now by
pressing the Up arrow key on your keyboard while in your Lua interpreter.
(This always works in WowLua, but may not work correctly if you are using
a standalone version of Lua.)
If it worked correctly, you should see the last line you typed (prnit(“Hello
Azeroth!“)) and your cursor should be at the end of the line. If it didn’t work,
you may instead see something similar to the following:
>ˆ[[A
That simply means your specific interpreter doesn’t handle history.
Although you may find this inconvenient at times, it certainly shouldn’t
hamper your capability to run through the examples correctly.
Quitting the Interpreter
When you are done running code in the interpreter, in most cases, you can
simply close the window. However, if you started the interpreter from a
command line and want to return to it, you can use one of the following
methods, depending on your operating system.
Microsoft Windows
On a Microsoft Windows system, Lua can be closed by pressing Ctrl+Z. This
inserts the following into your interpreter:
>ˆZ
In Windows this inserts a special character that means end-of-file, and it
causes the interpreter to quit. You can also press Ctrl+C to outright kill your
session.
Mac OS X
Mac OS X is a UNIX-based system, so the end-of-file character is different
from that of the Windows systems. At your prompt, press Ctrl+Dtoinsert
the end-of-file character and end the session immediately. You can also use
Ctrl+C to kill the session.
20 Part I Learning to Program
Working with Numbers
Almost every language has a way to calculate numeric values, and Lua is no
different. Type the following into your interpreter:
>print(2 + 2)
As expected, you will see 4as the response followed by another prompt.
Although it may not be the most convenient calculator, the interpreter does
enable you to perform calculations in your programs.
Basic Arithmetic Operations
Table 2-1 shows Lua’s basic arithmetic operators. You can use any of them to
compute a value.
Table 2-1: Lua Arithmetic Operators
OPERATION IN LUA EXAMPLE RESULT
Addition + > print(4 + 4) 8
Subtraction - > print(6 - 10) -4
Multiplication * > print(13 * 13) 169
Division / > print(10 / 2) 5
Exponentiation ˆ > print(13 ˆ2) 169
Modulo % > print(8 % 3) 2
Unary Negation - > print(- (4 + 4)) -8
In addition to these operators, you can use parentheses to group expressions
together to make more complex expressions. Consider the following example:
> print(2 * (1 + 2 + 3) ˆ3)
432
If you run this command with no parentheses in the expression itself, you
get an entirely different answer:
> print(2 * 1 + 2 + 3 ˆ3)
31
Parentheses are used to make an expression explicit and ensure that it
is evaluated properly. In the second case, the exponentiation operator is
Chapter 2 Exploring Lua Basics 21
processed first, followed by the multiplication operator and then the addition
operator, giving you the equivalent formula:
> print(2 + 2 + 27)
When in doubt, make your math explicit so it is easier to read when review
is needed in the future.
Scientific Notation
Occasionally, you’ll encounter an extremely large number such as
10,000,000,000,000,000 (10 ˆ15). Rather than type it out each time with zeros
or use parentheses to make sure it’s being calculated correctly inside another
formula, you can use scientific notation. Lua may automatically display large
numbers using scientific notation if printing them would be unwieldy. Run
the following commands:
>print(10 ˆ15)
1e+015
>print(10 ˆ-15)
1e-015
As you can see, Lua converts the numbers to scientific notation for the
purpose of printing them. Conveniently, you can also write numbers in
this fashion, which takes the first number and multiplies it by 10 raised to
thesecondnumber(theein between can be capitalized or lowercase). For
example:
> print(1.23456e5)
123456
> print(1.23456 * (10 ˆ5))
123456
> print(1234e-4)
0.1234
> print(1234 * (10 ˆ-4))
0.1234
You may not encounter numbers in scientific notation often, but under-
standing the output when Lua sends it back to you is important.
Hexadecimal Notation
Lua can natively convert a number in hexadecimal notation to the decimal
value. You can use this as a quick hex-to-decimal conversion, or you may
actually have a need to use hexadecimal notation in your systems. Lua expects
a zero, followed by the letter x, followed by a string of valid hex digits (09,
AF, af).
22 Part I Learning to Program
> print(0x1)
1
> print(0xF)
15
> print(0x10)
16
> print(0x10a4)
4260
When writing code, you can refer to numbers in this format and Lua will
convert them properly. As you can see from these examples, however, Lua
only responds in decimal or scientific notation, regardless of how the numbers
were input.
> print(2 * 0xF)
30
> print(0x10 ˆ2)
256
Understanding Floating Point
Every number in a standard Lua system is represented internally as a
floating-point number. For average use this won’t make a difference, but
it can have some odd implications. Here’s a simple (but confusing) example,
which uses some concepts that you won’t examine until later in this section of
the book:
> pointTwo = 1.2 - 1.0
> print(pointTwo < 0.2)
true
> print(pointTwo)
0.2
The number 0.2 cannot be accurately represented as a floating-point number,
so the programming language must do a bit of rounding when calculating
the value, and then again when printing it. The floating-point numbers
in Lua can accurately represent any integer from 10 ˆ–37 through 10 ˆ37,
so you shouldn’t encounter many of these problems. This rounding can,
however, serve as a source of calculation error when working with the real
numbers.
ON THE WEB
Much information regarding floating-point numbers and the implications
of the format exists out there on the Web. The following resources are all
extremely helpful if you’re interested in exploring the topic further:
(continued)
Chapter 2 Exploring Lua Basics 23
ON THE WEB (continued)
http://wikipedia.org/wiki/Floating point
http://docs.sun.com/source/806-3568/ncg goldberg.html
http://lua-users.org/wiki/FloatingPoint
Understanding Values and Variables
Like most other languages, Lua makes a distinction between values (such
as the string “Hello“ and the number 14) and variables (or references).
Understanding the underlying types of values and the distinction between a
value and a variable can be helpful while programming.
Exploring Values and Their Types
A value is the actual thing that is used, such as the number 17, or the string
“Hello“. The number 14 is a different value from the number 27,buttheyare
both number values. The string “Hello“ is a value, but it is a different type of
value than the two numbers. (There’s nothing tricky or complex that you need
to understand about values, I promise!)
There are eight primitive types in the Lua programming language and
every value you encounter will have one of them. You’ve already seen two
different types, number and string. The line between a string and number can
occasionally get blurry, such as drawing the distinction between the string “4“
and the number 4, but they remain discrete types.
Primitive Types
Table 2-2 describes Lua’s primitive types. Every value ends up being one of
these types, regardless of where it’s encountered in the language.
You will encounter each of these types through the course of your work, so
you should be aware of them.
Using the type() Function
Within Lua you can use the type() function to determine the type of a given
value, which gives you flexibility when it comes to validation and verification
in your programs. Type the following into your Lua interpreter:
>print(type(5))
number
24 Part I Learning to Program
Table 2-2: Lua’s Primitive Types
TYPE DESCRIPTION
number All numbers (including hexadecimal numbers and those using
scientific notation) have this type. Examples: 1,7313,1e5,
0xFFF1a
string A sequence of characters. Examples: “Hello“,“Test String“.
boolean The values true and false are of the boolean type.
function A function is a collection of statements that can be called, and is
introduced in Chapter 3.
table A table is a mix between a traditional hash table (dictionary) and
an array.
nil The value nil is of the special type nil.
thread A value of the thread type is a coroutine (limited lightweight
thread) that can be used for asynchronous computation.
userdata Userdata is traditionally a wrapper around some data structure
defined in the host language (usually C).
What you’ve done here is call the type() function with a value of 5,and
call the print() function with that result (you explore functions further in
Chapter 3). The output shows that the type of the value 5is number,asyoud
expect. Here are some other examples:
> print(type(“Hello Azeroth!“))
string
> print(type(2 * (1 + 2 + 3) ˆ3))
number
> print(prnit)
nil
In the third example note the misspelling of the variable prnit.Asyousaw
earlier in this chapter, that is a nil value, so the type () function returns nil as
expected. You can always use the type() function to find out which type your
value is.
Using Variables
Avariable can be seen as a temporary name for a specific Lua value, with the
caveat that the same value may have multiple names. An example here will
be more telling than words, so type the following into your interpreter (it may
not have output after each line, so just move on to the next line):
>x=4
>y=2
Chapter 2 Exploring Lua Basics 25
>print(x + y)
6
In this example, you take the name xandbindittothevalue4; and bind the
name yto the value 2. You then call the print function, and instead of using
the numbers 4and 2, you use the names xand y.
Valid Variable Names
A variable’s name or identifier has to start with a letter or an underscore
character. The name cannot contain anything other than letters, numbers, or
the underscore character. In addition, it can’t be any of the keywords that are
reserved by Lua: and,break,do,else,elseif,false,for,function,if,in,
local,nil,not,or,repeat,return,then,true,until,andwhile.Avariable
name is also case-sensitive, so the character ais different from the character A,
meaning that the following are all different identifiers:
MyVariable
myVariable
myvariable
Assigning Variables
Use the assignment operator =to bind a value to a variable name, with the
variable name on the left and the value on the right. Try the following examples
in your Lua interpreter:
>foo=14
>print(foo)
14
>foo = “Hello!“
>print(foo)
Hello!
The first example binds the value 14 to the identifier foo,andyoucanprint
and use that variable instead of the value itself. The second binds the value
“Hello“ to the identifier, changing what the variable refers to.
Variables can be used on the right-hand side of an assignment operator
as well, and what happens in those situations is different depending on the
context. Try the following in your interpreter:
>x=4
>y=x
>print(y)
4
>x=3
>print(y)
4
26 Part I Learning to Program
The first line simply binds the value 4to the identifier x. The second line,
however, assigns the value bound to the identifier xto identifier y. This means
quite literally that both xand yare names for the same value (the number 4).
As a result, when you run x=3, you simply change that binding, leaving
yintact.
TIP The distinction between values and variables can be confusing, especially
when working through more advanced topics. Use the Lua interpreter as a tool to
explore the rules and better understand what’s happening.
Assigning Multiple Variables
On some occasions you will assign more than one variable at a time, and a
convenient short form makes this easier. Run the following example:
>x,y=3,5
>print(x * y)
15
The assignment operator allows a list of variables on the left side and a list
of values on the right side. That’ll be a bit more useful when you get into
functions and return values. If there are more variables on the left side than
there are values on the right side, the remaining variables will be set to nil.
If there are more values on the right side, they will just be thrown away.
Comparing Values
In many cases, you will need to compare different values to see how they are
related. Several comparison operators (listed in Table 2-3) can be used.
Table 2-3: Comparison Operators
COMPARISON OPERATOR EQUIVALENT LUA OPERATOR
equality ==
less than <
greater than >
less than, or equal <=
greater than, or equal >=
not equal ~=
These operate exactly as you’d expect, but you can play in the Lua interpreter
to better understand them. When you print the result of a comparison, it will
be of the boolean type (that is, true or false).
Chapter 2 Exploring Lua Basics 27
> print(1 == 1)
true
> print(1 < 3)
true
> print(1 > 3)
false
> print(2 <= 2)
true
> print(1 >= 3)
false
> print(1 ~= 3)
true
The equality operators (== and ~=) can be used to compare any two values,
but the <,>,<=,and>= operators can only be used with values of the same type,
such as when comparing number to number or string to string; otherwise you
will get an error as follows:
> print(1 < “Hello“)
stdin:1: attempt to compare number with string
stack traceback:
stdin:1: in main chunk
[C]: ?
In other words, whereas the == and ~= operators work for all values, the less
than/greater than (<and >) family of operators is only defined for numbers
and string values.
Working with Strings
You’ve already been introduced to the string type, and you’ve used it to print
“Hello Azeroth!“ in the interpreter. In this section you examine strings in a
bit more detail.
Comparing Strings
The less than (<) and greater than (>) operators can be used on strings, but the
result depends on the way your system internally sorts the different characters.
For single character comparisons, the operator compares the two characters’
order in the character set; for multiple character strings, it compares the order
of the first two differing characters. For example:
> print(“a“ < “b“)
true
> print(“d“ >= “c“)
28 Part I Learning to Program
true
> print(“abcd“ < “abce“)
true
> print(“a“ < “A“)
false
> print(“abcd“ < “abcde“)
true
> print(“rests“ < “test“)
true
You may be surprised by the output from the fourth example. In the
standard Lua character set, uppercase English letters precede lowercase letters,
so the string “a“ is actually greater than the string “A“. In the fifth example, the
strings are identical until the first string runs out of characters. At this point,
Lua sees that the second string still has the letter “e“ and returns that the
second is greater. However, in the final example, even though the first string
is longer than the second one, the letter “ris less than the letter “t,sothe
whole string “rests“ is less than “test“.
Concatenating Multiple Strings
Strings in Lua are immutable, which means they cannot be changed without
creating an entirely new string. To add to a string, you use the special
concatenation operator (..), which enables you to take two strings and fuse
them together to make a new, larger string. Here are a couple of examples:
> x = “Hello“
> y = “Azeroth“
> print(x .. y)
HelloAzeroth
> foo = “a“ .. “b“ .. “c“ .. “d“ .. “e“
> print(foo)
abcde
Converting Numbers to Strings
As you can imagine, sometimes you will need to convert from numbers to
strings and, in most cases, Lua handles this for you. Try the following:
>print(“Number: “ .. 4)
Number: 4
Lua automatically converts the number 4to a string, and it’s added to the
string “Number: “. If you need to explicitly convert a number to a string, you
can use the tostring() function, as in the following example:
>x=17
> foo = tostring(x)
> print(type(foo))
string
Chapter 2 Exploring Lua Basics 29
The tostring() function takes whatever it is given (in this case a number)
and turns it into a string value.
Converting Strings to Numbers
Conversely, you may have a string of digits that you’d like to convert to a
number. Lua’s built-in tonumber() function takes a value and turns it into
a number. If the digits can’t be converted (such as when the string doesn’t
contain a number), the function returns the value nil. Here are some examples:
> x = tonumber(“1234“)
> print(type(x))
number
> print(x)
1234
> x = tonumber(“1e3“)
> print(type(x))
number
> print(x)
1000
Here the strings are converted into numbers, and the results are printed to
the screen. The tonumber() function has a few more tricks up its sleeve that
you can explore in Chapter 7.
Quoting Strings
So far, you’ve used double quotes to create strings, but there are several ways
to construct a string for use in Lua. When programming, it is considered proper
style to use the same type of quote character (as described in the following
sections) unless you have a specific reason for needing to use a different type.
This helps other people read your code without confusion.
Single Quote (’)
You can use the single quote mark ()also called a tick or tick markto
create a string, and this is standard convention. Nothing really special happens
here unless you need to include a tick mark within your string. Look at the
following examples:
> x = 'Hello’
> print(type(x))
string
> x = 'Isn’t it nice?’
stdin:1: `=´ expected near `it´
The first example works correctly and creates a new string with the text
Hello inside.
30 Part I Learning to Program
The second example throws an error that you should explore a bit more.
What Lua sees here is an identifier (x), the assignment operator (=), and a
string (’Isn’). Because Lua doesn’t require any whitespace between most
operations, it immediately starts the next part of the expression, which begins
with the identifier t. The next thing the interpreter sees is another identifier
called it, and doesn’t know what to do with it. In this case, the interpreter
infers that you meant to use the assignment operator and errors out with this
suggestion.
You can get around this by escaping the tick mark that is inside the string to
tell Lua that it’s part of the string instead of the end of it. Here’s an example:
> x = 'Isn\’t it nice?'
> print(type(x))
string
You tackle the details of string escaping shortly.
Double Quote (’’)
Thedoublequote() can be used the same way as the single quote, with the
same caveat of needing to escape embedded quote characters. Here are some
examples:
> x = “Hello“
> print(type(x))
string
> x = “Isn’t it nice?“
> print(type(x))
string
> x = “I play the game “World of Warcraft“
stdin:1: '=' expected near 'of'
The second works because the tick mark isn’t being used to delimit the
quote, but the inner quote in the third example needs to be escaped with a
backslash:
> x = “I play the game, \“World of Warcraft\““
> print(type(x))
string
Bracket Quote ([[ ]])
Lua has the concept of a long quote that enables you to include multiple
lines and internal quote characters. These quotes begin with the open bracket
character ([), have any number of equal signs (=), including 0, and then
Chapter 2 Exploring Lua Basics 31
another open bracket ([). The string closes only when it finds the opposite
combination (close brace, equal signs, close brace). Although this may seem
overly complex, it enables you to tailor-make your quote start/end for the
contents inside. Consider the following example:
> x = [[This is a long string, and I can include ' and “]]
> print(x)
This is a long string, and I can include ' and “
This includes no equal signs, which is the typical case. You could instead
include any number of them, if you needed to use the string “]]“ somewhere
in your larger string, as in this example:
> x = [==[This is a long string, and I can include ]], ', and “]==]
> print(x)
This is a long string, and I can include ]], ', and “
You may not find yourself using the [[Some String]] syntax often, but it can
be useful when the string spans multiple lines, or includes quote characters.
Escaping Special Characters
Beyond the ‘ and ‘‘ characters, there are other characters that aren’t necessarily
type-able but need to be included in a string. Try to make a multiline string
and see what happens:
>x = “First line
>> Second line“
stdin:1: unfinished string near '“First line’
Two things happen here: First, the prompt changes to two >> signs instead of
the normal one. This means you have an unfinished block and the interpreter
is waiting for you to finish the expression. Second, you get an error about an
unfinished string. This is a peculiarity in the Lua interpreter, because nothing
you can type on the second line will allow you to complete the expression.
You get around this by using \n, an escaped character that means newline.
Type the following:
>x = “First line\nSecond line“
>print(x)
First line
Second line
When constructing a string, you can include any of the escape sequences
listed in Table 2-4. Not all entries will have an effect when printed inside
World of Warcraft, but you should be aware of what valid sequences exist
because you may find them in preexisting strings.
32 Part I Learning to Program
Table 2-4: String Escape Sequences
SEQUENCE DESCRIPTION
\a audible bell
\b backspace
\f form feed
\n newline
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
\“ double quote
\’ single quote
\xxx ASCII character ddd
In World of Warcraft, you typically only encounter \n,\\,\“,\’,and\xxx,
because the output widgets in World of Warcraft don’t support the others.
NOTE More often than not, you will find escape codes used in localization
strings for addons. Some locales contain characters that aren’t type-able on all
keyboards, so they are inserted using the \xxx syntax. In the deDE localization for
World of Warcraft, the word Hunter is “J\195\164ger’’, which is typically
displayed as J ¨
ager. Localization is discussed further in Chapter 8.
Getting a String’s Length
There are two ways to obtain the length of a specific string: using the #operator
or using the string.len() function. The length of a string is often used when
validating or parsing strings.
Using the #operator before a string value returns the length as a number, as
shown in the following examples:
> print(#“Hello“)
5
> foo = “This is a test string“
> print(#foo)
21
You can use the built-in function string.len() to accomplish the same feat.
The period in between string and len means that this specific function is a
Chapter 2 Exploring Lua Basics 33
part of the string namespace (which you learn more about in Chapter 4). Type
the following into your interpreter:
>foo = “This is a test string“
>print(string.len(foo))
21
It returns the same value as the #operator because they both use the same
underlying method to calculate the length.
Boolean Values and Operators
The boolean type is relatively simple and only has two possible valuestrue
or falsebut as with many things in programming, there’s more than meets
the eye. Three logical operators can be applied to Boolean values: and,or,
and not.
Using the and Operator
The and operator is true when both of its arguments are true, and false when
either of them is false or doesn’t have a value. Examples help make this clearer:
> print(true and true)
true
> print(true and false)
false
> print(false and false)
false
> print(false and true)
false
This operator has one peculiarity that you might run into, illustrated by the
following example:
> print(false and “Goodbye“)
false
> print(true and “Hello“)
Hello
> print(true and 4)
4
In the first example, Lua evaluates only as much of the expression as
necessary. The and operator is being used, and it encounters a false value, so
it simply returns false without evaluating the rest of the expression (referred
to as short-circuit evaluation). In the last two examples, Lua does something
similar: it encounters a true value, so it returns the second value as its result.
That’s because the expression true and value evaluates to true if and only if
value itself would evaluate to true.
34 Part I Learning to Program
Using the or Operator
The or operator is true any time either of its arguments is true. Again, a simple
set of examples should make this clear, because there are only two possible
truth values:
> print(true or true)
true
> print(true or false)
true
> print(false or false)
false
> print(false or true)
true
This operator has a lower precedence than the and operator, so make sure you
are using it correctly, and include parentheses when necessary. For example:
> print(false and false or true)
true
> print(true and false or false)
false
In the first example, even though false and false turns out to be false,
it is part of a larger or statement, so the whole expression evaluates to true.
This isn’t Lua being confusing; it’s the underlying Boolean logic at play.
TIP You can use the behavior of the and and or operators to shorten some of
your expressions if you remember how they are evaluated. These operators allow
you to make the equivalent of the a ? b : c statement in C, using Lua. You will
encounter more useful examples of this later, but here’s a small example:
> print(true and “Hello“)
Hello
> print(false and “Hello“ or “Azeroth!“)
Azeroth!
Negation Using the not Operator
Simply enough, if you need to turn one Boolean value into the other, toggling
it, you can use the not operator:
> print(not true)
false
> print(not false)
true
> print(not 4)
Chapter 2 Exploring Lua Basics 35
false
> print(not “Hello“)
false
Again, because any value in Lua that is not false or nil evaluates to true,
you can even negate those values.
Understanding the nil Value
Earlier in this chapter, you encountered the following error message:
stdin:1: attempt to call global 'prnit’ (a nil value)
nil is a special thing that means lack of value in Lua. This is most often seen
when working with variables and tables (which you learn about in Chapter 4).
Type the following into your interpreter:
>print(SomeEmptyVariable)
nil
>print(type(SomeEmptyVariable))
nil
Because you have not bound the variable SomeEmptyVariable to anything
yet, it holds the special value nil,whichisoftypenil.Youcanusethis
knowledge to check if a variable is currently unset, as in the following
example:
> print(SomeEmptyVariable == nil)
true
> print(type(SomeEmptyVariable) == “nil“))
true
You can check to see if a value is equivalent to nil,usingthe== operator.
You can also check the type of the value, to see if that is nil.Besuretonote
the difference between the value nil and the string “nil“,becausethetype()
function always returns a string.
Exploring Scope
So far, each and every variable you have declared has been a global variable,
meaning it is accessible to all other parts of your program. There is another
type of variable, which is called local, in that its visibility to the rest of the
program is limited in some way. To fully understand the difference between
global and local variables you need to understand the scope (or visibility rules)
of blocks and chunks.
36 Part I Learning to Program
Blocks
The best way to illustrate a block is with an example, so type the following
into your Lua interpreter:
>do
>> local i = 7
>> do
>> local i = 10
>> print(“Inside: “ .. i)
>> end
>> print(“Outside: “ .. i)
>> end
Inside: 10
Outside: 7
Apart from the new keywords do,end,andlocal, you’re doing something
fairly simple here. You assign the value 7to the variable i, assign the value 10
to a new variable i, and then print each of them out as a string. In this case, the
do keyword tells the interpreter to begin a block, and the end keyword shows
where the block ends. It might make more sense when viewed indented:
do
local i = 7
do
local i = 10
print(“Inside: “ .. i)
end
print(“Outside: “ .. i)
end
By declaring the variable ias local, you’ve limited its scope to the current
block, in this case, the code between within the same do and end keywords.
You can access this variable as much as you like within those boundaries, but
outside that it’s as if the variable doesn’t exist.
In addition to manually creating blocks using do and end,certainLua
constructs such as for loops, while loops, and function definitions implicitly
begin a new block. You learn more about these constructs in Chapter 3.
NOTE In World of Warcraft, your addons will be competing with any number of
other addons that may use global variables. As a result, it is considered good
practice to use local variables in many cases.
Chapter 2 Exploring Lua Basics 37
Chunks
Earlier in this chapter, you received a stack traceback with an error, and it
may have referenced the main chunk. In Lua, a chunk is either the file being
executed, or the string that is being run. Variables are also limited in scope to
their specific chunk. This means a local variable declared at the top of one file
won’t be accessible in another file (they are different chunks).
In the Lua interpreter, each individual line you type is its own chunk, unless
you wrap it in a block (such as the preceding do ... end block). For this reason,
the following code will not work:
> local i = 10
> print(i)
nil
This is just a peculiarity of the way the Lua interpreter works. To get around
this, you can use do ... end to wrap multiple lines of code:
>do
>> local i = 10
>> print(i)
> end
10
Scope and visibility will be more important when you start working with
functions in Chapter 3, but it is important to understand the implication that
almost all variables are global, unless specified otherwise.
Summary
This chapter gave you a very broad introduction to fundamental concepts
central to the Lua programming language, including variables, values, types,
operators, and scope. Chapters 3 through 6 give you a more in-depth introduc-
tion to specific aspects of the language, as it relates to World of Warcraft. The
Lua programming language is used extensively outside WoW and a number
of good reference books are available on the language as a whole.
CHAPTER
3
Basic Functions and Control
Structures
Chapter 2 showed you the basics of the Lua programming language using the
print() and type() functions, without fully explaining what a function is. In
addition, basic control structures such as loops and conditionals haven’t been
introduced yet.
The first part of this chapter explains the concept of functions and guides
you through creating several of your own. The second half introduces the
basic looping and conditional statements.
Using Functions
A function is a portion of a program that can be used to simplify repeated tasks
or perform complex calculations. When a function is called it may be passed
several arguments, that is, data that the function can use for the duration of its
execution. When a function completes, it can return any number of values to
the calling portion of the program.
Creating a Function
The function keyword is used to create a new function, which can then be
stored in a variable or called directly. A basic function declaration looks like
this (type this into your Lua interpreter):
>hello = function()
>> print(“Hello World!“)
>> end
39
40 Part I Learning to Program
The function constructor begins where you type function() and continues
to the matching end keyword, with the code between these delimiters making
up the body of the function. The Lua interpreter recognizes the new block
of code and indents the prompt to show you’re continuing the same section
of code (until you type the final end). In this case, a function is created that
takes no arguments (more on this in the next section) and prints the string
Hello World before ending. The resulting function value is then assigned to
the variable hello. Test this function by running the following:
>hello()
Hello World!
Now, instead of typing print(“Hello World“) every time you want to print
that string, you can simply type hello() to call the new function. This is an
extremely simple example, but you use the full power of functions as you
move through the examples in this chapter.
Local Functions
The function constructor returns a new Lua value, so it can be assigned to a
local variable the same as any other value. This can be useful when defining
functions that are called within your addons, but need not be exposed for other
addons to call. Local variables are difficult to explore in the Lua interpreter
becauseeachlineofcodeisinitsownscope,butyoumayfindthetechnique
of using local functions useful when working through the rest of this book.
SYNTACTIC SUGAR
Lua provides a different way to define functions that is more conventional and
may be easier to read. Examine the following function definition:
function hello()
print(“Hello World!“)
end
When the Lua interpreter encounters this definition, it is converted into the
definition used in the previous section:
hello = function()
print(“Hello World!“)
end
That is to say, the two definitions end up running the same code in the
interpreter. Functions defined in this manner can be made local by adding the
keyword local before the function constructor, such as:
local function hello()
print(“Hello World“)
end
(continued)
Chapter 3 Basic Functions and Control Structures 41
SYNTACTIC SUGAR (continued)
When the local keyword is used, it is converted to roughly the following
version:
local hello
hello = function()
print(“Hello World“)
end
Function Arguments and Returns
When a function is called, it can be passed any number of arguments to be used
throughout the body of the function. In addition, a function may return any
number of values when it completes. This allows for the creation of dynamic
functions that can operate on values that are passed into the function, rather
than some static formula or process.
Simple and repetitive tasks such as converting degrees Celsius to degrees
Fahrenheit can easily be made into functions that use arguments and return
values.
Converting Celsius to Fahrenheit
The conversion formula given for temperature conversion is ‘‘Multiply the
temperature in degrees Celsius by 1.8 and add 32 to the result.’’ Instead of
performing this conversion with arithmetic each time, a function can be written
that takes a number as an argument and returns the converted value as the
answer. Type the following into your Lua interpreter:
convert_c2f = function(celsius)
local converted = (celsius * 1.8) + 32
return converted
end
Here, a function is created with a single argument, which is named celsius.
The first line of the new function calculates the converted value and the second
line returns it. To see how this works, type the following:
>print(convert_c2f(0))
32
>print(convert_c2f(-40))
-40
When the new function is called, the first argument passed to it (the
number 0) is assigned to a local variable named celsius (corresponding to
the name given in the function). This allows you to define the formula for
conversion without needing to know the specific number you are converting.
42 Part I Learning to Program
Empty Arguments
Try the following in your interpreter:
>print(convert_c2f())
stdin:2: attempt to perform arithmetic on local 'celsius' (a nil value)
stack traceback:
stdin:2: in function 'convert_c2f'
stdin:1: in main chunk
[C]: ?
When no value is passed as an argument, the argument gets the value of
nil. The first line of the convert_c2f function tries to multiply celsius by 1.8
and errors out because nil can’t be part of an arithmetic expression. A similar
error will occur if you pass other non-number values into this function.
No Return Values
Not every function you encounter will have a return statement because not
all functions need to return anything. The hello() function defined earlier
in this chapter is one such example. In these cases any assignments or other
expressions involving a call to the function will evaluate to nil. Here’s an
example:
>function hello() print(“Hello World!“) end
>test = hello()
Hello World!
>print(type(test))
nil
Functions as Lua Values
Each function in Lua is just a plain Lua value of the type function.These
values can be compared (using == and ~=), bound to variable names, passed
to functions, returned from functions, andusedaskeysintables(tablesare
explored in Chapter 4). A Lua value that is treated this way is called a first-class
object, and a language that supports functions in this way is said to have
first-class functions.
Run the following in your interpreter:
>hello = function() print(“Hello World!“) end
This creates a new function called hello. This value can now be compared
in the same way you’d compare any other Lua value.
>print(hello == hello)
true
>hello2 = hello
>print(hello2 == hello)
Chapter 3 Basic Functions and Control Structures 43
true
>hello2()
Hello World!
>hello2 = function() print(“Hello World!“) end
>print(hello2 == hello)
false
In the final lines of the preceding example, a new function is created and
bound to hello2. Even though the new function has the exact same definition
and body as hello, it is actually a distinct function.
Making Decisions with the if Statement
The if statement is the basis for decision making in Lua, and it supports
simple conditionals as well as more complex statements. The syntax of the
most basic if statement looks like this:
if <boolean expression> then
-- do something
end
Simple Conditionals
An if statement can be used to execute a block of code conditionally when
the Boolean expression evaluates to true. To better see this, type the following
into your interpreter:
function conditional_test(num)
print(“You input: “ .. num)
if (num == 7) then
print(“You found the magic number!“)
end
end
This example function prints whatever number it gets passed, but if the
number 7 is passed, it will print an additional special message. Input this
function into your interpreter, and then test it with the following:
>conditional_test(3)
You input: 3
>conditional_test(7)
You input: 7
You found the magic number!
>conditional_test(13)
You input: 13
44 Part I Learning to Program
As with other arithmetic and Boolean expressions, the parentheses around
the conditional are not strictly necessary, but they can certainly make code
easier to read.
Complex Expressions
In addition to simple Boolean conditions, Lua supports more complex expres-
sions so long as the expression evaluates to a Boolean value. That allows you
to combine multiple conditions using the logical operators (and,or)intoa
single complex condition. The following are all valid conditions (where name
and anonymous_flag are variables):
name
type(name) == “string“
(not anonymous_flag) and (type(name) == “string“)
The first example simply checks to see that the variable name is anything other
than nil or false. The second example checks to verify that the variable name is
a string, and the final example checks to see that the variable anonymous_flag
is either false or nil,andthename variable is a string.
Extended Conditionals
An extended form of the if statement allows you to chain multiple conditions
together, as well as provide a default for when no condition is matched. The
full syntax for the if statement is:
if <boolean expression> then
-- if part
elseif <boolean expression> then
-- elseif part
elseif <boolean expression> then
-- another elseif part
else
-- else part
end
When the interpreter runs this expression, it checks each condition in order,
stopping at the first expression that evaluates to true and running that portion
of the code. If none of the expressions are true, the code in the else section is
run. Not every if statement will include elseif or else options, but they are
always available if you need them.
Usingthisformofif/elseif/else ensures that only one action in the entire
if statement will be taken. If you were to write it using a series of simple if
statements, more than one may be called, as in the following example.
Chapter 3 Basic Functions and Control Structures 45
if <first condition> then
-- do something
end
if <second condition> then
-- do something
end
Both types of constructs are useful but you should ensure you are using the
correct one, so your program behaves correctly depending on whether you
need to take one action based on a condition, or evaluate multiple conditions
independently.
Displaying a Personalized Greeting
Conditionals can be used to verify the arguments to a function. For example,
consider a function that takes a name (or nil) and prints out a personalized
greeting. Define this function in your Lua interpreter:
function greeting(name)
if (type(name) == “string“) then
print(“Hello “ .. name)
elseif (type(name) == “nil“) then
print(“Hello friend“)
else
error(“Invalid name was entered“)
end
end
The first condition checks to see if the name argument is a string,in
which case it generates and prints a custom greeting. If the name argument is
nil, meaning nothing was passed into the function, it will print the generic
string Hello friend. Finally, if neither of the previous conditions match, the
function triggers a custom error message using the error() function. Test this
new function in your interpreter:
>greeting(“Frank“)
Hello Frank
>greeting()
Hello friend
>greeting(13)
stdin:7: Invalid name was entered
stack traceback:
[C]: in function 'error'
stdin:7: in function 'greeting'
stdin:1: in main chunk
[C]: ?
46 Part I Learning to Program
When the error() function is called, Lua provides the error message
supplied along with a stack traceback. In this case, you can see that the error
was triggered from the greeting() function, which was called from the main
chunk.
The preceding greeting() function could have been written without using
the elseif statement, by using nested if statements, as follows:
function greeting(name)
if (type(name) == “string“) then
print(“Hello “ .. name)
else
if (type(name) == “nil“) then
print(“Hello friend“)
else
error(“Invalid name was entered“)
end
end
end
The nested style is useful in certain situations when you have multiple
conditions but also need to have an else portion for each of them. In general,
use whatever style you consider to be more readable and appropriate for the
given situation.
Repeating Actions with the while Statement
Computers are often used to repeat tasks or simplify complex calculations that
would otherwise require manual repetition. Lua provides the while statement,
which will repeat a block of code as long as a specified condition is met. The
while statement’s syntax is:
while <boolean expression> do
-- body
end
The Boolean expression is evaluated on each and every repetition of the
loop, and the loop will continue as long as the condition evaluates to true.
Computing Factorials
The process of computing a number’s factorial is a good example of something
that is easily automated. The factorial of a number xis computed by multiplying
all of the numbers from 1to xtogether. Thus, 3factorial is 1*2*3.Ifa
function factorial() is defined, you can simply type print(factorial(9))
Chapter 3 Basic Functions and Control Structures 47
instead of print(9 * 8 *7*6*5*4*3*2*1). Define this function
now by typing the following definition into your interpreter:
function factorial(num)
local total = 1
while (num > 1) do
print(“total: “.. total .. “ num: “ .. num)
total = total * num
num = num - 1
end
return total
end
This function includes a print() statement that will show you what the
function does on each iteration of the loop. Before using this code in an addon,
remove that line from the function, or simply comment it out. For now, test
this in your Lua interpreter:
>print(factorial(5))
total: 1 num: 5
total: 5 num: 4
total: 20 num: 3
total: 60 num: 2
120
You can see each step of the loop and how the value is being calculated.
Using debug statements like this can be really handy when writing code, but
you have to remember to remove them before you release the code.
NOTE The condition of a while statement is checked prior to running the loop,
and again on each subsequent run of the loop. This means if the condition is never
met, the body of the while loop is never executed, and Lua just skips past it.
Differences Between while and repeat
The repeat/until loop is a variant of the while loop that has the following
form:
repeat
-- body
until <boolean expression>
The primary difference between the while/do loop and a repeat/until loop
is that the condition of a repeat loop is checked at the end of the computation,
so the loop of the body is always executed at least once. In other words,
the condition in a while statement is checked in order to continue the loop,
48 Part I Learning to Program
whereas the condition in a repeat loop is checked in order to exit the loop.
Here’s how you’d define a new factorial function using this construct:
function factorial2(num)
local total = 1
repeat
total = total * num
num = num - 1
until (num < 1)
return total
end
You can verify the results of this function by testing it with a few different
values:
>print(factorial2(1))
1
>print(factorial2(2))
2
>print(factorial2(3))
6
>print(factorial2(5))
120
If you happened to test these two functions with some unexpected value,
such as -3, you should see a difference between the results:
>print(factorial(-3))
1
>print(factorial2(-3))
-3
When running factorial(),thenum variable is already less than 1,so
the while body never runs; it simply returns the default value of 1.When
factorial2() is called, the body of the loop happens once, which causes the
different return value of -3.
Looping with the Numeric for Statement
As the preceding factorial function demonstrated, many loops begin at a simple
integer value and then either increment or decrement to some predefined limit.
In the case of factorial(9), the loop starts at 9and continues until it reaches 1.
Rather than managing this sort of loop yourself, the for statement provides
an easy way to write these loops:
for variablename = start_value, end_value, step_value do
-- body
end
Chapter 3 Basic Functions and Control Structures 49
Table 3-1 explains the different arguments that must be supplied to the for
statement.
Table 3-1: Arguments for Numeric for Loop
ARGUMENT DESCRIPTION
variablename A valid variable identifier, the counter variable
start_value A number, the initial value of variablename
end_value A number, the end value of the loop
step_value The number by which to increment the counter after each loop
The following are examples of simple for loops:
>fori=1,3,1do
>> print(i)
>> end
1
2
3
>for i = 3, 1, -1 do
>> print(i)
>> end
3
2
1
These two loops translate (roughly) to the following code blocks using while
loops:
do
local i = 1
while (i <= 3) do
print(i)
i=i+1
end
end
and
do
local i = 3
while (i >= 1) do
print(i)
i=i-1
end
end
50 Part I Learning to Program
When the step value in a for loop is not provided, Lua assumes a value of 1
for the loop. The earlier 1,2,3example can thus be written as follows:
for i = 1, 3 do
print(i)
end
Computing Factorials
The for loopcanbeusedtomakethefactorial() function even more clear.
Type the following definition into your interpreter:
function factorial3(num)
local total = 1
for i = 1, num do
total = total * i
end
return total
end
Rather than manually writing the terminal condition for the while or repeat
loop, you can just provide the for statement with a start value, and an upper
bound. This example uses the variable num, which is evaluated to a number
when the function is run.
Evaluation of Loop Conditions
In a for loop, the end_value and step_value are both calculated once, at the
start of the loop. As a result, variables and expressions can be used for these
values. These values cannot be changed mid-loop; they will have already been
calculated. Consider the following example:
>upper = 3
>fori=1,upper do
>> print(i)
>> upper = upper + 1
>> end
1
2
3
This example doesn’t loop forever because loop conditions are only evalu-
ated at the start of the loop.
Variable Scope in for Loops
When writing a for loop, remember that the counter variable name you supply
will automatically be made local to that block and won’t be accessible outside
that level:
>i=15
>fori=1,3doprint(i) end
Chapter 3 Basic Functions and Control Structures 51
1
2
3
>print(i)
15
In addition, changes made to the counter variable inside the loop do not
affect the iteration. For example, the assignment to iin the following loop
doesn’t actually advance the loop counter:
>for i = 1, 10 do
>> print(“Loop iteration: “ .. i)
>> i=i+1
>> end
Loop iteration: 1
Loop iteration: 2
Loop iteration: 3
Loop iteration: 4
Loop iteration: 5
Loop iteration: 6
Loop iteration: 7
Loop iteration: 8
Loop iteration: 9
Loop iteration: 10
If, for some reason, you need to save the control variable’s value, you can
declare a local variable just prior to the for loop, where you can save the
number you need, as in the following example:
upper = 10
do
local max
for i = 1, upper do
max = i
end
print(max)
end
When the loop terminates, max will be 10, which was the last value of the
control variable.
Summary
This chapter introduced you to functions and showed you two different
methods to create functions, using two different syntaxes. Conditionals and
control structures were introduced, enabling you to easily perform repeated
computations. The next chapter explores advanced techniques using functions
and control structures.
CHAPTER
4
Working with Tables
Keeping data in variables is handy when working on simple programs, but
larger projects require an easier way to store data. Consider a simple address
book program that enables you to electronically store contact information.
Using variables, that might look something like this:
alice_name = “Alice Applebaum“
alice_phone = “+1-212-555-1434“
alice_address1 = “114 Auburn Street“
alice_address2 = “Apt 14“
alice_city = “Atlanta“
alice_state = “GA“
As you can see, using this method for more than a few simple entries
would be unwieldy. Adding a new entry requires you to create a new variable
name and enter each of the details in a new variable. Computers are all about
automating processes, so there has to be a better way to deal with this.
Storing Data Using Tables
You may be familiar with tables or some analogous object from other pro-
gramming languages (arrays, records, dictionaries,hashtables).InLua,tables
are objects that can be used to store other (usually related) values.
To understand how to use tables, it’s important to grasp the concept of an
associative table; which is how tables in Lua are implemented. An associative
table is a collection of values that are each associated with a key. Code can then
request a given key from a table and receive the value that is paired with that
key, if such a pair exists.
53
54 Part I Learning to Program
Creating and Indexing Tables
Create a new table for Alice by running this code:
>alice = {}
In Lua, the table constructor {} creates a new table, in this case an empty
one. Here, the new table has been assigned to the variable alice.Youcan
index this table using square brackets and a key. Run the following:
>alice[“name“] = “Alice Applebaum“
>alice[“phone“] = “+1-212-555-1434“
>alice[“address1“] = “114 Auburn Street“
>alice[“address2“] = “Apt 14“
>alice[“city“] = “Atlanta“
>alice[“state“] = “Georgia“
Each line here tells Lua to look in the table alice using the provided key,
and set that value to whatever is on the right side of the assignment operator.
These elements can then be accessed later:
>print(alice[“name“])
Alice Applebaum
>print(alice[“address2“])
Apt 14
In each case, a key is matched up with a specific value and stored within the
table. Each of these examples uses a string as the key, but Lua actually allows
any value (except nil) to be used as a key. See this in the following example:
>alice[1] = “Test value“
>alice[2] = 14
>print(alice[1])
Test value
>print(alice[2])
14
Clearing an Element from a Table
When a table is indexed with a key that has not been set, the table will return
the special value nil. Run the following:
>print(alice[“fax“])
nil
This means, quite literally, that there is nothing stored in the table for the
given key. In order to clear a key/value pair from a table, you just assign that
key the value nil. Do this now to clear the two test values set previously:
>alice[1] = nil
>alice[2] = nil
Chapter 4 Working with Tables 55
Shortcuts for String Keys
Lua provides an easier way to index a table by string keys when those strings
are a single identifier. This is extremely useful when working with data tables.
Instead of typing this:
alice[“address1“] = “114 Auburn Street“
you can type the following:
alice.address1 = “114 Auburn Street“
This shortcut method only works when the key begins with a letter or
underscore character and consists of only letters, digits, and underscore
characters. In addition, the key cannot be a reserved Lua keyword (such as
end). All of the following identifiers are considered valid:
myTable.someKey
myTable.someKey12
myTable.some_Key
myTable._someKey
myTable.start
But these will cause an error:
myTable.12someKey
myTable.some-key
myTable.end
myTable.or
This method of indexing a table is only provided as a convenience, and
only works when your keys are in a specific format. You can still access the
‘‘invalid’’ keys using the full bracket notation.
Creating Populated Tables
In addition to using {} to create new empty tables, you can also use it to
create an already populated table. This is accomplished by providing a set of
key/value pairs within the constructor itself, using the following syntax:
myTable = {
[key1] = value1,
[key2] = value2,
...
}
56 Part I Learning to Program
Running the following can thus create an equivalent record for Alice:
alice = {
[“name“] = “Alice Applebaum“,
[“phone“] = “+1-212-555-1434“,
[“address1“] = “114 Auburn Street“,
[“address2“] = “Apt 14“,
[“city“] = “Atlanta“,
[“state“] = “Georgia“,
}
You can take advantage of shortcuts for string keys in the constructor too, by
typing someKey instead of [“someKey“]. This shortcut follows the same rules
as dot notation for table indexing. This shortens the example record to:
alice = {
name = “Alice Applebaum“,
phone = “+1-212-555-1434“,
address1 = “114 Auburn Street“,
address2 = “Apt 14“,
city = “Atlanta“,
state = “Georgia“,
}
TRAILING COMMAS IN TABLE CONSTRUCTORS
The last line of each of these table examples has a trailing comma before the
closing brace. The syntax of Lua allows this within tables so it is easier to add
new key/value pairs to the end of the definition. If Lua didn’t allow this and
you forget to add a comma before adding a new line, you would get a compi-
lation error.
When creating new tables in this format, having the trailing comma makes
adding new entries easier, so it is a common practice to include them on every
row.
Using Tables as Arrays
Lua tables have another unique property when they are used with consecutive
integer keys starting at 1. These tables can be used as lists of values and include
library functions for inserting values, removing values, and sorting the list.
Tables used in this manner are typically referred to as arrays,duetosome
similarities they share with arrays in other programming languages. More
specifically, the part of a table that has integer keys starting at 1is referred to
as the array part of the table.
Chapter 4 Working with Tables 57
Creating an Array
You can create a new array using the table constructor in one of the two
following ways (they are equivalent):
tbl = {
value1,
value2,
value3,
...
}
tbl = {
[1] = value1,
[2] = value2,
[3] = value3,
...
}
Inthefirstcaseyoucanomitthekeynamesentirely,andjustprovidea
comma-separated list of values. As you can see, arrays are just a special case
of tables. Each of the functions covered in this section is only reliable when
dealing with consecutive integer keys starting at 1.Althoughnil can be used
as a value in a table, it indicates that a value is missing, so care must be taken
to ensure that nil values don’t appear in the array part of a table.
The two types of table constructors can be mixed, so you can define a table
with an array part and key/value pairs at the same time. For example, the
following is a valid table definition that combines the use of all three definition
methods:
class_list = {
“Alice“,
“Bob“,
“Carol“,
class_name = “Foundations of Engineering and Computer Science“,
[“class_code“] = “ECS101“,
}
Getting the Length of an Array
Thesamelengthoperator(#) that was introduced in Chapter 2 for use on
strings is also used to get the length of the array part of a table. Test this now
with these quick examples:
>tbl = {“alpha“, “beta“, “gamma“, “delta“}
>print(#tbl)
4
58 Part I Learning to Program
>tbl={}
>print(#tbl)
0
>tbl={
>> “alpha“,
>> “beta“,
>> [“one“] = “uno“,
>> [“two“] = “dos“,
>> “gamma“,
>> }
>print(#tbl)
3
You can see that #only counts the elements in the array part. This operator
can be used to print the table’s elements without your needing to hardcode
the upper limit. For example:
>fori=1,#tbl do
>> print(tbl[i])
>> end
alpha
beta
gamma
Adding Elements to an Array
Adding an element to an array is as simple as associating the value to the next
integer key in sequence. More generally:
> tbl[#tbl + 1] = “new element“
This is a really tedious and error-prone way to do something relatively
simple. Lua provides a table.insert() library function that makes adding
elements a bit easier. The syntax for table.insert() is:
table.insert(tbl, [pos,] value)
The arguments are as follows:
tbl—The table to alter
pos (optional)The position at which to add the new element
valueThe value to insert
The second parameter being enclosed in brackets indicates that it is optional
and does not need to be included. If the position isn’t included, the new value
will be added to the end of the table.
Chapter 4 Working with Tables 59
Run the following in your interpreter to create a sample table and a function
that will allow you to easily print the contents of the array part of a table that
is passed in as an argument:
tmp = {“alpha“, “beta“, “gamma“}
function print_array(tbl)
fori=1,#tbl do
print(i, tbl[i])
end
end
To print the current list, use the following command:
>print_array(tmp)
1 alpha
2 beta
3 gamma
To add a new element to the end of the list, call table.insert() with the
table you’d like to alter and the value you’d like to add:
>table.insert(tmp, “delta“)
>table.insert(tmp, “epsilon“)
>print_array(tmp)
1 alpha
2 beta
3 gamma
4 delta
5 epsilon
To insert a new value at a given position, call table.insert() with the
optional second parameter pos, a number that indicates at what position you’d
like to add the element. When you insert a value in this way, all elements after
the given position will be renumbered and moved up.
>table.insert(tmp, 3, “zeta“)
>print_array(tmp)
1 alpha
2 beta
3 zeta
4 gamma
5 delta
6 epsilon
When using the position argument, it’s important to make sure you’re
supplying a valid number. The position should always be between 1,which
inserts the value at the front of the list, and #tmp + 1,whichinsertsitafterthe
60 Part I Learning to Program
current last element. If you supply a value outside this range, the results are
unpredictable.
Removing Elements from an Array
Lua includes a function to remove elements from a table, and the syntax is
similar to its companion table.insert():
value = table.remove(tbl [, pos])
This function takes up to two parameters:
tbl—The table to alter
pos (optional)The element to remove from the table
The function signature is written as if it was an assignment. This is shorthand
notation to show that the function also returns something:
valueThe value removed from the table
Again, the brackets around pos show that it is an optional parameter. When
a position isn’t included, Lua will remove the last element in the table (that is,
the element at the #tbl position).
To remove the last element of a table, use the following command:
>removed = table.remove(tmp)
>print_array(tmp)
1 alpha
2 beta
3 zeta
4 gamma
5 delta
>print(removed)
epsilon
By simply calling table.remove() with only a table argument, the last
element has been removed and we’re left with the rest of the table.
Here’s how to remove a specific element in a table:
>removed = table.remove(tmp, 3)
>print_array(tmp)
1 alpha
2 beta
3 gamma
4 delta
>print(removed)
zeta
When an element is removed from the middle of the table (including the first
element), all other elements are renumbered and shifted down. This ensures
Chapter 4 Working with Tables 61
that the elements of the array are always numbered properly so the array part
functions all work properly.
Just because a function has return values doesn’t mean you have to do
anything with them. You could just as easily call table.remove(),ignoring
the return value entirely.
Sorting the Elements of an Array
When an array contains basic elements such as strings and numbers that can
be easily compared, there is a standard library function to sort the list. The
syntax of the table.sort() function follows:
table.sort(tbl [, comp])
The second argument to table.sort() is covered in detail in Chapter 5, but
the first argument is the table that you would like to sort. You can call this
function and pass it a table to be sorted as the first argument:
>print_array(tmp)
1 alpha
2 beta
3 gamma
4 delta
>table.sort(tmp)
>print_array(tmp)
1 alpha
2 beta
3 delta
4 gamma
Because the values in this table are strings, they are sorted alphabetically,
in ascending order (this is the default). If the table contained numbers, they
wouldbesortedinthesameway.
A simple sort like this won’t be effective for more complex values (such as
tables), or when the values in an array are mixed (such as strings and numbers).
Chapter 5 will show you how to use the second argument to table.sort()to
custom tailor the sort function for these situations.
Using Tables as Namespaces
You’ve already been introduced to a few functions that are grouped together:
table.insert()
table.remove()
table.sort()
62 Part I Learning to Program
When functions are grouped together in this manner, they are said to be
part of a namespace,inthiscase,thetable namespace. Namespaces provide a
logical grouping of functions that are related, collected in a Lua table. Because
tables can hold function values, the preceding functions are also accessible
using:
table[“insert“]()
table[“remove“]()
table[“sort“]()
Creating a new namespace is a matter of writing your new functions,
creating a new table, and setting the appropriate key/value pairs in your table.
Creating a Namespace of Utility Functions
You’ve already written a few utility functions that might be handy to keep
around, such as convert_c2f(). You can create a new namespace to start
storing these functions by defining a new table:
>util = {}
Adding Functions to a Namespace
You have two different ways to add functions to a namespace: by indexing the
table and storing the value of an existing function, or by defining the function
directly as part of the namespace.
Storing an Existing Function
If you’ve closed your previous Lua session, redefine your Celsius to Fahrenheit
conversion function:
function convert_c2f(celsius)
return (celsius * 1.8) + 32
end
Now that you have a function to which you can refer, run the following
code to store it in the util table:
>util.celsius2fahrenheit = convert_c2f
This function can then be accessed directly from the util table:
>print(util.celsius2fahrenheit(0))
32
>print(util.celsius2fahrenheit(-40))
-40
Chapter 4 Working with Tables 63
Defining a New Function
Rather than define a function with a name and then set it as part of the
namespace, you can define the function directly as part of the namespace. Run
the following code:
function util.factorial(num)
local total = 1
fori=1,numdo
total = total * i
end
return total
end
You may recall from Chapter 3 that this method of function definition is
syntactic sugar and is translated by Lua into the following:
util.factorial = function(num)
local total = 1
for i = 1, num do
total = total * i
end
return total
end
Using the first form is often the most convenient way to define functions,
and it makes the code easier to read compared to the alternative methods.
More often than not, when you read a namespace definition, you will see it in
this form; however, as always, feel free to develop your own style.
Object-Oriented Programming with Tables
Tables can also be used for a different type of programming called object-oriented
programming. In this type of programming, data is described as objects, which
contain methods, special functions that act directly on or through that object. Lua
provides some simple mechanisms to enable object-oriented programming,
but does not strictly enforce any particular style of programming.
Creating a Non-Object-Oriented Counter
To illustrate some of the benefits this type of programming provides, run the
following in your interpreter:
-- Create a new scope for local variables
do
64 Part I Learning to Program
-- Create a counter that cannot be accessed outside this scope
local counter = 0
-- Global functions to interact with counter
function counter_get()
return counter
end
function counter_inc()
counter = counter + 1
end
end
This block of code makes a simple, one-way counter that can’t be decre-
mented, but can be retrieved and incremented via the counter_get() and
counter_inc() functions. Explore this by running the following in your
interpreter:
>print(counter_get())
0
>counter_inc()
>counter_inc()
>print(counter_get())
2
>counter = counter - 1
stdin:1: attempt to perform arithmetic on global 'counter' (a nil value)
stack traceback:
stdin:1: in main chunk
[C]: ?
You can see that the counter variable is not accessible outside of the created
scope and thus can’t be altered without calling the provided functions. This
code implements a single counter when, in fact, you might need more than
one. Because these functions are tied to a specific counter variable, they are
very limited.
Using Tables as Simple Objects
The following is a different implementation for the simple counter, making the
counteranobjectwithtwomethods,get and inc. Unlike the first example, the
counter can be altered directly without calling the functions. Run the following
code in your interpreter:
counter = {
count = 0
}
function counter.get(self)
Chapter 4 Working with Tables 65
return self.count
end
function counter.inc(self)
self.count = self.count + 1
end
This program allows you to do the following:
>print(counter.get(counter))
0
>counter.inc(counter)
>print(counter.get(counter))
1
In this implementation, the actual counter variable is stored in a table (which
serves as the object). Each of the functions that interact with this value has an
argument named self, which is expected to be a counter object. You could
make a new counter by running the following:
>counter2 = {
>> count = 15,
>> get = counter.get,
>> inc = counter.inc,
>> }
>print(counter2.get(counter2))
15
Because the functions are just Lua values and they are designed to work on
an argument rather than some magical hidden variable, you can copy them
into your counter. As a matter of fact, the functions will work correctly even if
you call counter.get() butpassitthecounter2 object:
>print(counter.get(counter2))
15
>print(counter.get == counter2.get)
true
This should be no surprise because you’re just moving and copying refer-
ences to the same functions around. Although this implementation is definitely
more convenient than the first attempt, it can be made even easier. Right now,
you have to call the function and pass in the counter object, causing you
to type the object’s name twice. Lua provides a bit of syntactic sugar that
helps you.
Using : to Call Object Methods
In the preceding example you can refer to get and inc as object methods
because they are written to be called within the context of an object. Lua
66 Part I Learning to Program
provides a bit of syntactic sugar that makes calling an objects methods easier.
Instead of typing counter.get(counter),youcancallcounter:get().
Lua translates counter:get() into counter.get(counter), saving you a bit
of typing and making code easier to read. This all happens behind the scenes
and prevents from you having to pass the object in every time you make a
method call.
Defining Functions Using :
You can use the :operator to define functions, making this type of program-
ming even more natural. When this happens, Lua includes an implicit first
argument called self. That’s why you used the variable name self in the
previous example.
Redefine the earlier functions by typing the following into your interpreter:
counter = {
count = 0
}
function counter:get()
return self.count
end
function counter:inc()
self.count = self.count + 1
end
This code is roughly equivalent to the following definition:
counter = {
count = 0
}
function counter.get(self)
return self.count
end
function counter.inc(self)
self.count = self.count + 1
end
Test this new version with the following code:
>print(counter:get())
0
>counter:inc()
>counter:inc()
>print(counter:get())
2
Chapter 4 Working with Tables 67
COMMON ERRORS
If you attempt to call a method that expects the self argument with a period
instead of a colon, you might get an error similar to this:
stdin:2: attempt to index local 'self' (a nil value)
Most of the time, when you get this error, it means you are accidentally call-
ing a method without passing a first argument, or you used a period where
you meant to use a colon.
Making a Better Counter
The counter program still has room for improvement because the way new
counters are created is relatively clunky. Run the following to define a more
robust counter system:
-- Create a new scope for local variables
do
local function get(self)
return self.count
end
local function inc(self)
self.count = self.count + 1
end
function new_counter(value)
if type(value) ~= “number“ then
value = 0
end
local obj = {
count = value,
get = get,
inc = inc,
}
return obj
end
end
This example provides a single global function called new_counter,which
takes the initial value of the counter as an argument. It returns a new object
containing two methods and the counter value itself. This type of function is
typically called a factory function because it just returns new objects each time
you call it. Run a few tests to ensure the system works properly:
>counter = new_counter()
>print(counter:get())
68 Part I Learning to Program
0
>counter2 = new_counter(15)
>print(counter2:get())
15
>counter:inc()
>print(counter:get())
1
>print(counter2:get())
15
Although the implementation may seem a bit more complex than the
previous attempts, creating and manipulating new counters is extremely easy.
Choose whichever implementation makes the most sense in your code.
Extending Tables with Metatables
Each table in Lua is capable of having a metatable attached to it. A metatable is
a secondary table that gives Lua extra information about how that table should
be treated when it is used. For example, by default, when you try to print a
table you are given a string that looks something like table: 0x30d470,which
isn’t extremely readable. Lua provides a way to change this behavior using
metatables and metamethods.
Adding a Metatable
A metatable is nothing more than a table used to store extra information about
the tables to which it is attached. They can be passed around, attached to
multiple tables, and altered at any time. To begin redefining the behavior of
a table, you must create a metatable and attach it to a table object, using the
setmetatable() function. This function takes two arguments:
tbl—The table to alter
mtThe table to attach to tbl
In addition, setmetatable() returns a single argument, the table you passed
in as the first argument. This can be helpful when creating new tables to pass
directly to setmetatable(). Run the following code to create some tables to
play with, and attach the same metatable to each of them:
tbl1 = {“alpha“, “beta“, “gamma“}
tbl2 = {“delta“, “epsilon“, “zeta“}
tbl3 = {}
mt = {}
setmetatable(tbl1, mt)
setmetatable(tbl2, mt)
setmetatable(tbl3, mt)
Chapter 4 Working with Tables 69
You can verify the metatable has been set correctly by using the
getmetatable() function. This function simply takes a table as the first
argument and returns the metatable, or nil if no metatable is attached.
>print(getmetatable(tbl1) == mt)
true
Now that you have an object with a metatable, you can begin redefining the
behavior of the table.
Defining Metamethods
Ametamethod is nothing more than a function stored with a specific key
in a metatable. There are several possible metamethods, and they take a
varying number of arguments. Each metamethod begins with two underscore
characters. You can find a full list in the Lua Reference Manual (available online
at http://www.lua.org), but the most frequently used ones are shown in
Table 4-1.
Table 4-1: Relevant Metamethods
METAMETHOD ARGUMENTS DESCRIPTION
___add 2 Defines the behavior when used in addition
operations.
___mul 2 Defines the behavior when used in multiplication
operations.
___div 2 Defines the behavior when used in division
operations.
___sub 2 Defines the behavior when used in subtraction
operations.
___unm 1 Defines the behavior when negated (unary minus).
___tostring 1 Defines the behavior when the table is an
argument to tostring(). This also affects the
print() function, which calls tostring()
directly.
___concat 2 Defines the behavior when used with the
concatenation operator (..)
___index 2 Defines the behavior when the table is indexed
with a key that doesn’t exist in that table.
___newindex 3 Defines the behavior when a previously unset key
in the table is being set.
70 Part I Learning to Program
Defining Basic Arithmetic Using ___add, ___sub, ___mul, and
___div
Each of the arithmetic metamethods ___add,___sub,___mul,and___div takes
two arguments and can (in theory) return anything you’d like. However, keep
the following in mind:
The result of one operation may be part of a larger arithmetic expression.
If you return a non-number from your metamethod, you should ensure
it is capable of handling further arithmetic.
If you return nil, it will break any arithmetic expression it is a part of, so
it’s best to avoid that.
The following function defines addition between two tables as a new table
with the elements of the first table’s array part, followed by the elements of
the second’s array part. Add the following function to your Lua interpreter:
function mt.___add(a,b)
local result = setmetatable({}, mt)
-- Copy table a in first
fori=1,#ado
table.insert(result, a[i])
end
-- Copy table b in second
fori=1,#bdo
table.insert(result, b[i])
end
return result
end
To simplify the function, the arguments have been named aand b.Thefirst
line creates a new results table and makes sure to set the metatable correctly;
without this the result might not work in a larger arithmetic expression. The
rest of the function is straightforward, copying the elements of each table to
the new resulting table. Here is a simple test:
>add_test = tbl1 + tbl2
>print(#add_test)
6
>fori=1,#add_test do print(i, add_test[i]) end
1 alpha
2 beta
3 gamma
4 delta
5 epsilon
6 zeta
Chapter 4 Working with Tables 71
The metamethod correctly handles the addition and creates a new table
with the results of the addition. The other basic arithmetic operations could
be defined in the same way. Instead of returning a table, these functions could
return some meaningful number that can be used as part of a larger formula.
Defining Negation Using ___unm
The unary minus (negation) operator, __unm, expects exactly one argument,
and should return the result of the argument being negated. In these examples,
this will mean reversing the array part of the given table. Run the following
code:
function mt.___unm(a)
local result = setmetatable({}, mt)
-- Reverse through the elements of the array
for i = #a, 1,-1 do
table.insert(result, a[i])
end
return result
end
Test table negation with a few examples:
> unm_test = -tbl1
> for i = 1, #unm_test do print(i, unm_test[i]) end
1 gamma
2 beta
3 alpha
> unm_test = -tbl1 + tbl2
> for i = 1, #unm_test do print(i, unm_test[i]) end
1 gamma
2 beta
3 alpha
4 delta
5 epsilon
6 zeta
Creating Meaningful Output with ___tostring
In the current example, it would be useful to print the table and have it display
the elements rather than the unique string Lua provides. You can accomplish
that using the ___tostring metamethod, which takes a single argument (the
table) and should return a string.
Run the following code:
function mt.___tostring(tbl)
local result = “{“
for i = 1, #tbl do
72 Part I Learning to Program
if i > 1 then
result = result .. “, “
end
result = result .. tostring(tbl[i])
end
result = result .. “}“
return result
end
Because you know the input will be a table, you start the string with the {
character. This function then loops through each element of the array. If the
loop is beyond the first element, a comma is added to the string to separate
each value. This is done so you don’t have an extra comma at the end of the
output. Then the value itself is concatenated onto the result string. Finally,
when the loop is complete, you close the brace and return the string:
>print(tbl1)
{alpha, beta, gamma}
>print(tbl2)
{delta, epsilon, zeta}
>print(tbl3)
{}
When working with more complex objects, it can be very useful to provide a
meaningful text representation of your data, so the ___tostring metamethod
can be extremely handy.
Concatenating Tables Using ___concat
For these tables, concatenation will end up being the same thing as addition, so
you can simply use that function for the ___concat metamethod, as well. Both
metamethods take in two arguments and return a single result. In addition,
both are typically chained together, so you’ll need to ensure the resulting
object is also capable of concatenation. Run the following test:
>mt.___concat = mt.___add
>print(tbl1 .. tbl2)
{alpha, beta, gamma, delta, epsilon, zeta}
Because the ___tostring metamethod is still active, the resulting table is
converted to string representation, even when printed like this.
Exploring Fallback Tables with ___index
Normally, when a table does not have a value associated with a given key, nil
is returned. That makes sense for run-of-the-mill tables, but at times it is more
Chapter 4 Working with Tables 73
appropriate to take other action instead. The ___index metamethod allows
that to happen, following this procedure:
1. Code tries to access an unassociated key in a table.
2. If the table has an ___index metatable entry that is another table, look
up the same key in that table and return it (or nil if it doesn’t exist).
This may possibly trigger the ___index metamethod of the second table,
making a chain.
3. If the table has an ___index metatable entry that is a function, call the
function with the table and the key as arguments, and return the result.
Example Using Tables
Let’s expand on the previous example by creating a table with an ___index
metamethod that allows for the translation of English phrases into German.
Run the following code:
tbl4 = {[“Night elf“] = “Nachtelf“}
setmetatable(tbl4, mt)
enUS_defaults = {
[“Human“] = “Human“,
[“Night elf“] = “Night elf“,
}
mt.___index = enUS_defaults
This example creates a new table that contains the German localization of
the English phrase Night elf. In addition, there is a default table that contains
the English phrases Human and Night elf. If the answer isn’t found when tb14
is indexed, Lua will look in the metatable’s ___index entry and return that
result. See this in action yourself:
>print(tbl4[“Night elf“])
Nachtelf
>print(tbl4[“Human“])
Human
>print(tbl3[“Night elf“])
Night elf
Because the metatable is shared between the four tables being used in this
exercise, if you access the Night elf or Human key in the table, you will get the
English version of the phrase back. The ___index metatable entry here allows
you to provide partial localization for the German language by displaying the
English words by default when a translation isn’t found.
74 Part I Learning to Program
Example Using Functions
Instead of using a table for the ___index entry, you can specify a function
that takes two arguments: the table itself and the key being requested. This
function enables you to add logic to the indexing of tables. Run the following
code, which allows you to avoid having a long table of defaults where the keys
and the values are the same:
defaults_mt = {
___index = function(tbl, key)
if type(key) == “string“ then
print(“Return default value of '“ .. key .. “' for key: “ .. key)
return key
else
return nil
end
end,
}
setmetatable(enUS_defaults, defaults_mt)
Then test it with the following examples:
>print(tbl4[“Night elf“])
Nachtelf
>print(tbl4[“Human“])
Human
>print(tbl4[“Gnome“])
Return default value of 'Gnome' for key: Gnome
Gnome
>print(tbl4[1])
nil
Note that the second to last example prints a message in addition to returning
the value. In fact, a metamethod that is a function can do any number of things.
Catching Creation of Keys with ___newindex
Unlike the ___index metamethod, which is designed to handle keys being
requested from a table, the ___newindex metamethod can be used when a new
key has been set in the table. Specifically, it is called whenever an assignment
is made to a non-existing key in a table.
___newindex takes three arguments:
tblThe table being indexed
keyThe key being used to index the table
valueThe value to assign to table[key]
Chapter 4 Working with Tables 75
When this metamethod is set, it is responsible for actually making the
assignment happen. This can be used to stop a value from ever being set in the
first place. Run the following code in your interpreter:
function mt.___newindex(tbl, key, value)
if key == “banana“ then
error(“Cannot set a protected key“)
else
rawset(tbl, key, value)
end
end
The rawset() function here allows you to bypass the metatable (covered
in the next section), to prevent your metamethod from being called again.
As long as this metatable is set, you will be unable to (through conventional
means) set the key [“banana“] in any of the example tables, as shown in the
following:
> tbl1.apple = “red“
> print(tbl1.apple)
red
> tbl1.banana = “yellow“
stdin:3: Cannot set a protected key
stack traceback:
[C]: in function 'error'
stdin:3: in function <stdin:1>
stdin:1: in main chunk
[C]: ?
> print(tbl1.banana)
Return default value of 'banana' for key: banana
banana
Because the metamethod errors instead of setting the new entry, you have a
pseudo-‘‘protected’’ key in your tables.
Bypassing Metatables
When writing functions for the ___index and ___newindex metamethods, it
may be necessary to bypass the metatable when getting or setting a value. This
is accomplished using the rawget() and rawset() functions.
value =rawget(tbl, key)
The rawget() function takes the table to query and the key to look up, and
returns the value of that key in the table without using the metatable for
lookups. When you are writing a function that serves as a metamethod for a
table, it is typically best to use rawget() to access values in that table.
76 Part I Learning to Program
rawset(tbl, key, value)
To set a value in a table without hitting the metatable, you can use the
rawset() function. It takes in the table to be altered, the key to use, and the
value to be placed in the table. You will encounter tables with ___newindex
metamethods less frequently than those with ___index metamethods, but it’s
good to understand what tools are available, in case you need them.
Summary
In this chapter you learned how to use Lua tables to store data that can be
easily read and indexed. Arrays were introduced as a special subset of tables
with helper functions to insert/remove and sort array tables. Namespaces
of functions were introduced along with basic object-oriented programming.
Finally, you learned how to extend tables using metatables.
The next chapter introduces you to more advanced features of functions and
control structures.
CHAPTER
5
Advanced Functions and
Control Structures
The functions and control structures introduced in Chapter 3 were relatively
simple but gave you the capability to create nontrivial programs. This chapter
introduces more advanced versions of functions and loops that allow you to
accomplish the following:
Create functions with a variable number of arguments
Return multiple values from a function
Loop through the key/value pairs in the hash part of a table
Sort an array with table data
Multiple Return Values
In Lua, functions are able to return more than one value in a return statement,
which makes accomplishing some tasks more natural. For example, colors
in World of Warcraft are represented as both hexadecimal values (such as
99CCFF) as well as numeric percentages of red, green, and blue (such as 0.6,
0.8,1.0). As a result, it can be useful to convert the hexadecimal values (which
are widely used on the web) to the decimal equivalents.
Converting Hex to RGB
An example of a hexadecimal string is FFCC99, where the first two characters
represent the value of the color red as a number between 0 and 255 in
hexadecimal. The second set of characters is the value of green, followed by
blue. The string.sub() function can be used to split the string into its three
77
78 Part I Learning to Program
component color strings, whereas the tonumber() function can convert the
string into a number. If the tonumber() function is called with the red part of
the string “FF“, it won’t return a meaningful result:
>print(tonumber(“FF“))
nil
By default, the tonumber() function expects the number to be a decimal
number (that is, in base-10), so it can’t convert this base-16 number. The
second argument of tonumber() specifies the base of the string that is being
converted. In this case:
>print(tonumber(“FF“, 16))
255
Because the output needs to be a number between 0.0 and 1.0, this value
can be divided by 255 to obtain the percentage value. Add a definition for
ConvertHexToRGB() as follows:
function ConvertHexToRGB(hex)
local red = string.sub(hex, 1, 2)
local green = string.sub(hex, 3, 4)
local blue = string.sub(hex, 5, 6)
red = tonumber(red, 16) / 255
green = tonumber(green, 16) / 255
blue = tonumber(blue, 16) / 255
return red, green, blue
end
Test this function with a few sample values:
>print(ConvertHexToRGB(“FFCC99“))
1, 0.8, 0.6
>print(ConvertHexToRGB(“FFFFFF“))
1, 1, 1
>print(ConvertHexToRGB(“000000“))
0, 0, 0
Assigning Multiple Values
To get the results of a function with multiple return values such as
ConvertHexToRGB(), you can use the following syntax:
var1, var2, var3, var4 = someFunction()
This calls someFunction() and assigns the first return to var1, the second
return to var2, and so on. If there are more returns than variables, the extra
returns are just discarded. In the case that there are more variables than
returns, the remaining variables are set to nil.
Chapter 5 Advanced Functions and Control Structures 79
Missing Return Values?
When you are working with multiple return values, a few odd things can
happen. Look at the following example:
>print(ConvertHexToRGB(“FFFFFF“))
1, 1, 1
>print(ConvertHexToRGB(“FFFFFF“), “SomeOtherArgument“)
1, SomeOtherArgument
Where did the other returns go? They were eaten by the following rule:
When a function call with multiple return values is the last argument to another
function, or the last argument in a multiple assignment expression, all of the
return values are passed or used. Otherwise, only the first return value is used or
assigned.
You can see this behavior with the assignment operator in the following
example:
>a, b, c, d = ConvertHexToRGB(“FFFFFF“), “some“, “more“, “arguments“
>print(a, b, c, d)
1, some, more, arguments
Because the call to ConvertHexToRGB() is followed by additional values,
Lua only uses the first return from the function call. There are a few technical
reasons for this limitation, but it should not affect you very often. The exception
to the rule can be seen in the following example:
>a, b, c, d = “first argument“, ConvertHexToRGB(“FFFFFF“)
>print(a, b, c, d)
first argument, 1, 1, 1
TIP When working with multiple return values, you can always wrap the function
call in parentheses to limit it to a single return value, as follows:
> print((ConvertHexToRGB(“FFFFFF“)))
1
Multiple Return Values in World of Warcraft
Several World of Warcraft API functions return multiple values. For example,
the function GetRaidRosterInfo() takes a character’s raid index (a number)
and returns the following information:
The name of the character
The character’s rank in the raid (leader, assistant, and so on)
What subgroup the character is in
80 Part I Learning to Program
The character’s level
The character’s class (localized)
The character’s class (capitalized, in English)
The name of the zone the character is currently in
Whether the character is online
Whether the character is dead
If the character is a main tank or main assist
Whether the character is master looter
This function provides a ton of information, but, typically, when you need
one of the items, you need more than one. In this case, it’s more efficient for
the game client to return each of these items every time the function is queried,
rather than having 11 different API functions.
SELECTING SPECIFIC VALUES
Functions with multiple return values provide a unique set of challenges, such
as how to get at values that aren’t at the start of the return list. There are
two easy ways to do this: using dummy variables and using the select()
statement.
Taking the ConvertHexToRGB() example, how could you extract just the
green value?
Using a Dummy Variable
The function is going to return three results regardless of how you call it, but
you can use dummy variables to throw away the results that aren’t interesting.
For example, you may see something that looks like this:
local _, g = ConvertHexToRGB(“FFFFFF“)
Because the underscore character is a valid identifier, it can be used to store
values, but most sane programs choose more valid variable names. The under-
score identifier has become somewhat of a de facto standard when you need
to throw away the result of a function call simply because it’s easy to type,
and most likely not already in use, but its use is still considered bad practice.
Instead of using the underscore as a dummy variable, it’s better to give each
variable a meaningful name, and only use those that are necessary. That way if
you ever need to look at that code in the future, you have a hint of what other
information is available. Some situations can’t be handled using this method,
but Lua provides a utility function to compensate.
(continued)
Chapter 5 Advanced Functions and Control Structures 81
SELECTING SPECIFIC VALUES (continued)
Using the select() Function
The select() function was designed to help solve this problem, by allowing
you to choose a specific argument from a given list. This function takes any
number of arguments, the first of which tells the function what to do. When
select() is passed the “#“ string as the first argument, it simply returns
the number of arguments in the second part of the function. If select() is
passed a number value, it returns that argument from the list, followed by
anything after it. After this initial argument, select() takes any number of
arguments, comma separated.
Confused yet? Look at a few examples:
>print(select(“#“, “alpha“, “beta“, “gamma“))
3
>print(select(1, “alpha“, “beta“, “gamma“))
alpha, beta, gamma
>print(select(2, “alpha“, “beta“, “gamma“))
beta, gamma
>print(select(3, “alpha“, “beta“, “gamma“))
gamma
>third = select(3, “alpha“, “beta“, “gamma“)
>print(third)
gamma
If you just need to get a single value from the list, you can assign it directly
to the variable, or wrap the select() call in parentheses so the extra values
are thrown away.
You may find this function useful when working with some of the longer
World of Warcraft API functions, such as GetRaidRosterInfo(). If you only
need a single return, you can isolate it using a call to select().
Accepting a Variable Number of Arguments
Many functions are designed to take a specific number of arguments, such
as the tonumber() function, which takes a string, and optionally, a number
base for the conversion. Other functions make more sense when they accept
a variable number of arguments. Consider a function that calculates the
arithmetic mean of a set of numbers. A simple version of this function that
works with two arguments might look something like this:
function mean(num1, num2)
return (num1 + num2) / 2
end
82 Part I Learning to Program
Unfortunately, if you need to compute the mean of three numbers, you
would need to do it manually, call the function twice, or write a new function
that takes three arguments instead. As you can imagine, this is highly ineffi-
cient, and Lua provides an easier way to write these types of functions so they
can accept a variable number of arguments.
Declaring a Vararg Function
Functions with a variable number of arguments are called vararg functions for
short, and they use an ellipsis (three periods) in their function declaration to
indicate they take any number of arguments.
In Lua, the ellipsis can only appear as the last argument in a function
declaration. Whenever the ellipsis is then used in the body of the function,
the arguments that were supplied in the vararg slot are substituted. Take the
print() function, which already accepts a variable number of arguments, and
extend it by running the following code:
function test_print(...)
print(“testing“, ...)
end
This function takes in any number of arguments and then passes them to
the print() function, adding its own text to the start of the list. The output
from running this function looks like this:
>test_print(“alpha“, “beta“, 13, “gamma“)
testing, alpha, beta, 13, gamma
When the function is run and Lua encounters the ... symbol, it replaces it
with the list of arguments that were passed to the function. As a result, it can
be used in the following ways:
-- Pass the arguments to another function
print(...)
-- Assign the arguments to variables
local var1, var2, var3 = ...
-- Construct a new table with the arguments
local tbl = {...}
The preceding example could be used to make a new function called
newtable(), which takes in a set of arguments and makes a new table with
those arguments in the array part of the table:
function newtable(...)
return {...}
end
Chapter 5 Advanced Functions and Control Structures 83
Test this function now:
>tbl = newtable(“alpha“, “beta“, “gamma“)
>for i=1, #tbl do
>> print(i, tbl[i])
>> end
1, alpha
2, beta
3, gamma
Using select() with ...
The select() function makes working with vararg functions very easy,
because it can provide the number of arguments passed, as well as allow you
to easily iterate through them without needing to assign them to variables.
Consider the following function that takes a list of arguments and prints a line
for each argument including the index and the argument itself:
function printargs(...)
local num_args = select(“#“, ...)
for i=1, num_args do
local arg = select(i, ...)
print(i, arg)
end
end
Sample output:
>printargs(“alpha“, “beta“, 13, “gamma“)
1, alpha
2, beta
3, 13
4, gamma
This method lets you avoid creating a new table every single time, and
allows the value nil to be passed as an argument. Remember that the length
operator and the table library functions are only reliable when the array table
does not contain any ‘‘holes’’ in the form of nil values. Run the following
function definitions in your interpreter:
function test1(...)
local tbl = {...}
for i = 1, #tbl do
print(i, tbl[i])
end
end
function test2(...)
for i = 1, select(“#“, ...) do
84 Part I Learning to Program
print(i, (select(i, ...)))
end
end
You can see an example of this issue by running the following:
>test1(“alpha“, “beta“, “gamma“, nil)
1, alpha
2, beta
3, gamma
>test2(“alpha“, “beta“, “gamma“, nil)
1, alpha
2, beta
3, gamma
4, nil
The first example stuffs the arguments into a table and then tries to get the
length of the table. Because there is a nil value in the middle of the table,
getting the length could return either two or four. This sort of unpredictability
is specifically why you should use the second example.
In addition the first function needs to create a new table on each call, which
will allocate and use more memory in the long run. The version using select()
has no such hidden cost.
Generic for Loops and Iterators
Chapter 3 introduced the for statement, which allows you to repeat a compu-
tation over a series of numbers by supplying a start value, end value, and a
value by which to increment the counter after each loop. Chapter 4 introduced
storing data in both the array part and the hash part of Lua tables. Until this
point there has been no way to loop through the elements of the hash part
of the table, but Lua provides a more generic form of the for statement that,
when combined with an iterator function, allows just that.
Wikipedia defines an iterator as ‘‘an object which allows a programmer
to traverse through all elements of a collection, regardless of its specific
implementation.’’ In Lua specifically, you use an iterator function along with
some extra information to loop through a collection.
Syntax of Generic for
The generic for loop syntax is a bit different than the numeric for loop:
for val1, val2, val3, ... in <expression> do
-- body of for loop
end
Chapter 5 Advanced Functions and Control Structures 85
A generic for loop can return many variables on each iteration (as many as
defined by the iterator function, actually). Immediately after the for keyword,
you supply a list of variable names that are used to store the returns on each
iteration of the loop. The generic loop then determines what to traverse by
evaluating <expression>, which should return the following three values:
An iterator function that can be called on each iteration of the loop
state, used by the iterator function on each subsequent call
An initial value for the iterator value
Luckily, unless you plan to write your own iterator functions, you won’t
have to deal with any of this directly. A number of prewritten functions will
create your iterators for you.
Traversing the Array Part of a Table
ipairs() is one such function that allows you to traverse the array part of
a table without using the numeric for loop. Some programmers prefer this
syntax to that of the numeric for loop. Run the following example:
>tbl = {“alpha“, “beta“, “gamma“}
>for idx, value in ipairs(tbl) do
>> print(idx, value)
>> end
1, alpha
2, beta
3, gamma
The ipairs() function takes a table and returns all the information the for
loop requires to traverse the array part of the table, including the iterator
function itself. Each call to the iterator function returns the numeric index of
the element, and the element itself. These variables can be named whatever
you’d like and, as always, are local to the scope of the for loop (meaning they
cannot be accessed outside of that scope).
You can explore the ipairs() function a bit more by running the following
in your interpreter:
>print(ipairs(tbl))
function: 0x300980, table: 0x3072c0, 0
>print(tbl)
table: 0x3072c0
It appears the ipairs() function returns an iterator function, the state (in this
case it’s just the table you passed in), and the initial value for the iterator (0).
There’s no real magic going on here, just a useful function allowing you to
loop through array tables.
86 Part I Learning to Program
Traversing an Entire Table
Another function, called pairs(), allows you to traverse a table in its entirety,
including both the array part and the hash table part. The usage is the same as
ipairs();justpassitthetableanduseitaspartofagenericfor loop:
>tbl = {“alpha“, “beta“, [“one“] = “uno“, [“two“] = “dos“}
>for key, value in pairs(tbl) do
>> print(key, value)
>> end
1, alpha
2, beta
one, uno
two, dos
TRAVERSING USING PAIRS()
In the preceding example, the pairs() function seemed to traverse the
table in the order the elements were added to the table, but this is just a
coincidence. The specific order in which elements will be visited is unspecified
by this function, even for numeric keys. If you specifically need to traverse
the table’s numeric elements in order, you should instead use the ipairs()
function, which can guarantee this. The lack of order when using pairs() is
due to the way hash tables are implemented, as a collection of associated
key/value pairs with no internal order.
When using the pairs() function, you must ensure you don’t add any ele-
ments to the table. This is because pairs() calls the next() function, which
carries the following warning in the Lua 5.1 Reference Manual:
‘‘The behavior of next is undefined if, during the traversal, you assign any
value to a nonexistent field in the table. You may, however, modify existing
fields. In particular, you may clear existing fields.’’
If you add an element to the table during the traversal, the iteration may
simply not work, it may terminate early, or it may throw an error. It’s important
to keep this in mind when working with an iteration using pairs().
In addition, you may encounter an error if you try to clear a key that was not
previously set by assigning nil to it. This is due to the way tables are imple-
mented. In general you should ensure you only ever assign to keys that existed
prior to the iteration.
Clearing a Table
As stated in the Lua 5.1 Reference Manual for next(),youcanclearthe
elements of a table while traversing it using pairs(). The following code will
clear a table of all set elements:
for key, value in pairs(tbl) do
Chapter 5 Advanced Functions and Control Structures 87
tbl[key] = nil
end
Because pairs() works for all keys of a table, this is a quick way to ensure
you’ve cleared all elements (in the event you need to re-use a table, for
example). Note that this is different than just running tbl = {}, which would
create a new table entirely, rather than clearing the existing table. You can see
this by printing the value of the table before and after, and verifying that they
are different:
>tbl = {“alpha“, “beta“, “gamma“}
>print(tbl)
table: 0x131800
>tbl={}
table: 0x131ac0
Using Other Iterators
A number of other functions in Lua can be used to generate iterators that
are extremely useful. The string.gmatch() function can be used with Lua
pattern matching to create iterators over strings, and specific matches within
that string. You learn more about this function and Lua pattern matching in
Chapter 6, but here are some examples:
>for word in string.gmatch(“These are some words“, “%S+“) do
>> print(word)
>> end
These
are
some
words
>for char in string.gmatch(“Hello!“, “.“) do
>> print(char)
>> end
H
e
l
l
o
!
Sorting an Array of Table Data
The built-in table.sort() function only allows you to sort number and string
data by default. Fortunately, table.sort() enables you to pass in a function to
do the actual comparisons between elements, with the library function doing
the overall sort based on the results of your function. This means you can write
your own function to determine which of two tables is bigger when it comes to
sorting.
88 Part I Learning to Program
Define Example Data
For the examples in this section you need some sample data to sort. Define the
following in your Lua interpreter:
guild = {}
table.insert(guild, {
name = “Cladhaire“,
class = “Rogue“,
level = 80,
})
table.insert(guild, {
name = “Draoi“,
class = “Druid“,
level = 80,
})
table.insert(guild, {
name = “Deathsquid“,
class = “Deathknight“,
level = 68,
})
Default Sort Order
By default, this list is sorted in the order it was inserted, because it’s using the
array part of the table. Run the following to verify this:
>for idx, value in ipairs(guild) do
>> print(idx, value.name)
>> end
1, Cladhaire
2, Draoi
3, Deathsquid
Rather than print value itself, which would show table: 0x3003a0 instead
of something meaningful, this code indexes the table and prints the value
associated with the key name. This code segment could be altered to print the
class, or the level if so desired.
Creating a Comparison Function
If you try to sort this data using table.sort(), you will get an error because
Lua doesn’t know how to compare table values (to determine what makes one
table less than another).
>table.sort(guild)
attempt to compare two table values
Chapter 5 Advanced Functions and Control Structures 89
stack traceback:
[C]: in function 'sort'
stdin:1: in main chunk
[C]: ?
The table.sort() function takes a second argument specifically for this
purpose, to allow the programmer to define how values should be compared.
This function takes two arguments, and returns true if the first argument is
less than the second argument, and false if the second argument is less than
or equal to the first argument. That means you can sort two tables based on
their member fields, or some other criteria you specify. Write the following
function, which will compare two of the elements based on name:
function sortNameFunction(a, b)
return a.name < b.name
end
Although the function is extremely short, that’s all that is required to sort the
array by name. Pass this function in as the second argument to table.sort():
>table.sort(guild, sortNameFunction)
>for idx, value in ipairs(guild) do
>> print(idx, value.name)
>> end
1, Cladhaire
2, Deathsquid
3, Draoi
To reverse the sort order, just reverse the order of the comparison (note that
the position of b.name and a.name inthecomparisonhavechanged):
function sortNameFunctionDesc(a, b)
return b.name < a.name
end
Sort with this new function:
>table.sort(guild, sortNameFunctionDesc)
>for idx, value in ipairs(guild) do print(idx, value.name) end
1, Draoi
2, Deathsquid
3, Cladhaire
Creating a More Complex Sort Function
Assume you’d like to sort the preceding data by level and then by character
name. You can write a function to sort by level, but there’s no way to tell in
90 Part I Learning to Program
what order it will put the two level 80 characters. The following comparison
function accomplishes this more complex sort:
function sortLevelNameAsc(a, b)
if a.level == b.level then
return a.name < b.name
end
return a.level < b.level
end
All that is required is a simple check to see if the two levels are the same,
and if they are, to compare the names of the characters. A sort function can
beascomplexasyouneed,aslongasitreturnstrue when the first argument
should be sorted less than the second argument:
>table.sort(guild, sortLevelNameAsc)
>for idx,value in ipairs(guild) do print(idx, value.name, value.level) end
1, Deathsquid, 68
2, Cladhaire, 80
3, Draoi, 80
Summary
This chapter introduced the concepts of vararg functions, generic for loops,
iterators, and sorting complex data in arrays. These concepts are relatively
advanced, but come up often when designing and writing a new addon.
CHAPTER
6
Lua Standard Libraries
Throughout the first part of this book, a number of Lua standard library
functions have been introduced and used in code examples. Although this
book does not cover every single Lua function included in the World of
Warcraft implementation of Lua, this chapter introduces you to the some of
the most prevalent functions that you will need when developing addons.
In addition to the Lua standard libraries, this chapter covers some functions
specific to WoW that aren’t really part of the game API itself. These functions
aregroupedattheendofthechapter.
NOTE The details in this chapter cover the parts of the Lua API that are most
relevant to WoW. You can find a full reference for Lua online at
http://lua.org/manual/5.1. This manual is also available in print: Lua 5.1
Reference Manual by R. Ierusalimschy, L. H. de Figueiredo, and W. Celes, Lua.org,
August 2006 (ISBN 85-903798-3-3).
In addition, the chief architect of Lua has written an easy-to-read book about the
Lua programming language that covers these (and more) functions in depth. You
can find a version of this book written for an older version of Lua at
http://lua.org/pil. If reading the older version is confusing, you can find the
second edition at many online bookstores: Programming in Lua (second edition)
by Roberto Ierusalimschy, Lua.org, March 2006 (ISBN 85-903798-2-5).
Each function is this chapter is presented with what is called the function’s
signature. A function signature describes what values are returned by the
function, as well as what arguments are taken by the function. For example,
consider the fictional function foo():
someReturn = foo(arg1, arg2)
91
92 Part I Learning to Program
In this example, the function foo() takes two arguments (arg1 and arg2)
and returns a single value someReturn. These signatures can also indicate
optional arguments, by enclosing them in square brackets:
somereturn = foo(arg1 [, arg2])
This notation indicates that the second argument to foo() is optional. When
you see this, you should consult the description of the function and arguments
to determine the behavior of the function because it varies.
Table Library
The table library provides several functions that allow you to easily add
elements, remove elements, and sort array tables. In addition, a utility function
is provided that works outside of the array part of the table, returning the
maximum numeric index used in the table. The former functions all operate
exclusively on the array part of the table, whereas the latter can be used on
any type of table.
str =table.concat (table [, sep [, i [, j]]])
The table.concat() function concatenates all entries of the array part of
a table, with an optional separator string sep. Given an array where all
elements are strings or numbers, it returns table[i]..sep..table[i+1] ...
sep..table[j]. The default value for sep is the empty string, the default for
iis 1, and the default for jis the length of the table. If iis greater than j,it
returns the empty string.
> tbl = {“alpha“, “beta“, “gamma“}
> print(table.concat(tbl, “:“))
alpha:beta:gamma
> print(table.concat(tbl, nil, 1, 2))
alphabeta
> print(table.concat(tbl, “\n“, 2, 3))
beta
gamma
This function is an easy way to print the elements of the array part of a
table. As you can see, sep can be any string (including the newline character)
because it’s just concatenated with the entries in the table.
table.insert (table, [pos,] value)
The table.insert() function inserts a new element into the array, optionally
at position pos, shifting other elements up to make space, if necessary. The
default value for pos is n+1, where n is the length of the table. Therefore, a call
of table.insert(t,x) inserts xat the end of table t.
Chapter 6 Lua Standard Libraries 93
> tbl = {“alpha“, “beta“, “gamma“}
> table.insert(tbl, “delta“)
> table.insert(tbl, “epsilon“)
> print(table.concat(tbl, “, “))
alpha, beta, gamma, delta, epsilon
> table.insert(tbl, 3, “zeta“)
> print(table.concat(tbl, “, “))
alpha, beta, zeta, gamma, delta, epsilon
max =table.maxn (table)
The table.maxn() function returns the largest positive numerical index of the
given table, or zero if the table has no positive numerical indices. To do its
job, this function does a linear traversal of the entire table. Unlike most table
functions, table.maxn() considers numerical keys instead of integer keys, so
numerical constants and rational numbers are counted as well.
> tbl = {[1] = “a“, [2] = “b“, [3] = “c“, [26] = “z“}
> print(#tbl)
3
> print(table.maxn(tbl))
26
> tbl[91.32] = true
> print(table.maxn(tbl))
91.32
value =table.remove (table [, pos])
The table.remove() function removes an element from the given table, shifting
down other elements to close the space, if necessary. It returns the value of the
removed element. The default value for pos is n, where n is the length of the
table, so a call table.remove(t) removes the last element of table t.
> tbl = {“alpha“, “beta“, “gamma“, “delta“}
> print(table.remove(tbl))
delta
> print(table.concat(tbl, “, “))
alpha, beta, gamma
table.sort (table [, comp])
The table.sort() function sorts the array part of a table by reordering the
elements within the same table. If comp is given, it must be a function that
receives two table elements and returns true when the first is less than the
second (so that not comp(a[i+1],a[i]) will be true after the sort for all i). If
comp is not given, the standard Lua operator <is used instead.
94 Part I Learning to Program
This sort algorithm is not stable, which means that elements considered
equal by the given comparison function may have their order changed by
the sort.
> tbl = {“alpha“, “beta“, “gamma“, “delta“}
> table.sort(tbl)
> print(table.concat(tbl, “, “))
alpha, beta, delta, gamma
> sortFunc = function(a,b) return b < a end
> table.sort(tbl, sortFunc)
> print(table.concat(tbl, “, “))
gamma, delta, beta, alpha
String Utility Functions
Lua provides several utility functions for working with and manipulating
strings. Each of these functions is available as object-oriented method calls,
as well as the library calls themselves. For example, the following two calls
accomplish the same thing:
> str = “This is a string“
> print(string.len(str))
16
> print(str:len())
16
Table 6-1 describes the various utility functions and illustrates their use.
Table 6-1: String Utility Functions
FUNCTION DESCRIPTION EXAMPLE(S)
string.len(s) Receives a string and
returns its length.
The empty string ““
has length 0.
Embedded zeros are
counted, so
“a\000bc\000“
has length 5.
> print(string.len(“Monkey“))
5
string.lower(s) Returns the input
string with all
uppercase letters
changed to
lowercase. All other
characters are left
unchanged. The
definition of what an
uppercase letter is
depends on the
current locale.
> test = “Hello World!“
> print(string.lower(test))
hello world!
> printtest:lower())
hello world!
Chapter 6 Lua Standard Libraries 95
FUNCTION DESCRIPTION EXAMPLE(S)
string.rep(s, n) Returns a string that is
the concatenation of n
copies of the string s.
> print(string.rep(“Hello“, 3))
HelloHelloHello
> test = “foo“
> print(test:rep(3))
foofoofoo
string.reverse(s) Returns a string that is
the string s reversed.
> print(string.reverse(“Test“))
tseT
> test = “Hello World!“
> print(test:reverse())
!dlroW olleH
string.sub(s, i
[, j])
Returns the substring
of s that starts at i and
continues until j; i and
j may be negative. If j
is absent, it is assumed
to be equal to -1
(which is the same as
the string length). In
particular, the call
string.sub(s,1,j)
returns a prefix of s
with length j, and
string.sub(s, -i)
returns a suffix of s
with length i.
> test = “Hello World“
> print(string.sub(test, 1, 3))
Hel
> print(test:sub(1, -1))
Hello World
> print(test:sub(-3, -1))
rld
string.upper(s) Receives a string and
returns a copy of this
string with all
lowercase letters
changed to uppercase.
All other characters are
left unchanged. The
definition of what a
lowercase letter is
depends on the
current locale.
> test = “Hello World!“
> print(string.upper(test))
HELLO WORLD!
> print(test:upper())
HELLO WORLD!
Formatting New Strings
Throughout the book, you’ve used the concatenation operator to make new
strings and format longer messages. This code to generate longer strings ends
up being extremely difficult to read, and difficult to maintain. Lua provides a
utility function called string.format(formatstring, ...) that will format a
list of arguments according to a defined format.
96 Part I Learning to Program
A format string can contain literal characters and special conversion codes
that are used along with the arguments to create the final result. Conversion
codes begin with a percent sign (%) and contain one of the following specifiers
that indicate what type of data the argument should be treated as:
%cTakes a number argument and formats it as the ASCII character that
corresponds to the number.
%d, %iTakes a number argument and formats it as a signed integer.
%oTakes a number argument and formats it as an octal number.
%uTakes a number argument and formats it as an unsigned integer.
%xTakes a number argument and formats it as a hexadecimal number,
using lowercase letters.
%XTakes a number argument and formats it as a hexadecimal number,
using capital letters.
%eTakes a number argument and formats it as scientific notation, with
a lowercase e.
%ETakes a number argument and formats it as scientific notation, with
an uppercase E.
%fTakes a number argument and formats it as a floating-point number.
%g and %GTakes a number and formats it according to either %e (or %E
if %G is specified) or %f, depending on which is shortest.
%qFormats a string so it can safely be read back into a Lua interpreter.
%sTakes a string and formats it according to the supplied options.
Several options can be used in a conversion specification between the
percentsignandthetypespecier.Thefollowing options can be included, in
this specific order:
1. Sign specification (either a +or a ) that causes a sign to be printed with
any number. By default, the sign is only printed with negative numbers.
2. A padding character (either a space, or a 0) that will be used when
padding the result to the correct string width. By default, any results will
be padded with spaces to meet the correct width, if specified.
3. An alignment specification that causes the result to be left-justified or
right-justified. The default is right-justification, whereas a character
will make the result left-justified.
4. A width specification that specifies the minimum width of the resulting
string.
5. A precision specification that dictates how many decimal digits should
be displayed when formatting a floating-point number. When speci-
fied for strings, the resulting string will be cut off at this number of
characters.
Chapter 6 Lua Standard Libraries 97
Confused yet? More often than not, you’ll only use a very small subset of
these options, but it’s good to understand the abilities and limitations of the
string formatting system. The examples in Table 6-2 should help clarify the
basics of string formatting.
Table 6-2: Example Format Strings
COMMAND RESULT
string.format(“%%c: %c“, 83) %c: S
string.format(“%+d“, 17.0) +17
string.format(“%05d“, 17) 00017
string.format(“%o“, 17) 21
string.format(“%u“, 3.14) 3
string.format(“%x“, 13) D
string.format(“%X“, 13) D
string.format(“%e“, 1000) 1.000000e+03
string.format(“%E“, 1000) 1.000000E+03
string.format(“%6.3f“, 13) 13.000
string.format(“%q“, [[“One“, “Two“]]) “\“One\“, \“Two\““
string.format(“%s“, “monkey“) monkey
string.format(“%10s“, “monkey“) monkey
string.format(“%5.3s“, “monkey“) mon
IN WORLD OF WARCRAFT
WoW includes an extra option for string.format() that allows you to
choose a specific argument from the argument list, rather than having them
in consecutive order. This option is not included in standard Lua 5.1, so you
will need to use one of the interpreters provided on the book’s website
(http://wowprogramming.com/utils) to test this. If you are using the
WoWLua addon, it should work correctly.
To select a specific argument, include the number of the argument, followed
by the dollar sign ($), immediately after the percent sign (%). For example:
> print(string.format(“%2$d, %1$d, %d“, 13, 17))
17, 13, 17
The first type identifier is modified to request the second argument, and the
second identifier consumes the second argument to the format string. When
selecting parameters in this way, you can’t skip any and leave them unused.
(continued)
98 Part I Learning to Program
IN WORLD OF WARCRAFT (continued)
If you use parameters 1 and 3, you must also use parameter 2. You can mix
parameter selection and normal type identifiers in the same format string
without any issues.
WoW specifically includes this functionality to provide support for multiple
languages. For example, the following string appears in English:
Cladhaire’s Shadow Word: Pain is removed.
In German, the phrase used in this same situation is:
’Shadow Word: Pain’ von Cladhaire wurde entfernt.
As you can see, the order of the arguments is swapped based on the way
the phrase is constructed for German clients. Without parameter selection,
WoW would have to handle each of these cases specifically, which would get
very messy. Instead, the client uses string.format() along with parameter selec-
tion to craft these messages.
The English format string is “%s’s %s is removed.“, and the German for-
mat string is “’%2$s’ von %1$s wurde entfernt.“. Rather than maintain
a long list of special messages, format strings are used to make the client
consistent.
Pattern Matching
A common theme you will find when writing addons is the need to match
and parse text supplied by the game against a given pattern. Lua provides a
number of utility functions to accomplish these tasks. These functions can use
patterns to describe what to search for when matching against a given string.
Character Classes
Patterns can use any of the character classes described in Table 6-3. Each class
is designed to match a subset of all characters in a specific way. For example,
the character class %s can be used to match any whitespace character, and %a
canbeusedtorepresentanyletter.
In addition, with any of the character classes that have a percent sign
followed by a letter, the letter can be changed to uppercase to serve as a
shortcut for the complement to the character class. In other words, %S will
match any character that is not a space, and %A will match any character that
is not a letter.
Take a look at some examples. Given the test string “abc ABC 123 !@# \n
\000 %“, Table 6-4 shows what will be matched by a given pattern.
Chapter 6 Lua Standard Libraries 99
Table 6-3: Character Classes
CLASS MATCHES
x(where xis not one of the
magic characters
ˆ $()%.[]*+-?)
The character xitself.
.(period, or full stop) Any character.
%a Any letter.
%c Any control character.
%d Any digit.
%l Any lowercase letter.
%p Any punctuation character.
%s Any space character.
%u Any uppercase letter.
%w Any alphanumeric character.
%x Any hexadecimal digit.
%z The character with representation 0 (for
example,\000).
%x (where xis any
non-alphanumeric character)
Represents the character x. This is the standard
way to escape the magic characters. Any
punctuation character (even the non-magic
ones) can be preceded by a %when used to
represent itself in a pattern. For example, to
include a percent sign in the resulting string you
would include %% in the format string.
[set] Any characters included in set, which can be
specified as a range of characters by listing the
range with a hyphen (such as A-Z). All classes
defined in this table may also be used as a part
of set, including the other characters, which just
represent themselves. For example, [%w_]
matches all alphanumeric characters plus the
underscore character, and [0-9%l%-] matches
all digits plus the lowercase letters and the -
character.
[ˆset] The complement of any set (as previously
defined). Therefore, [ˆ%s] matches any
non-space character.
100 Part I Learning to Program
Table 6-4: Example Patterns
PATTERN STRING MATCHED
“a“ a
“.“ a
“%a“ a
“%c“ \n
“%d“ 1
%l“ a
%p !
%s space
%u A
%w a
%x a
%z \000
%% %
Pattern Items
Each of the character classes previously defined can be used in the pattern
items described in Table 6-5.
Table 6-5: Using Pattern Items
PATTERN MATCHES
A single character class
followed by a -
Zero or more repetitions of characters in the class. Unlike *,
these repetition items always match the shortest possible
sequence.
A single character class Any single character in the class.
A single character class
followed by an *
Zero or more repetitions of a character in the class. These
repetition items always match the longest possible
sequence.
A single character class
followed by a +
One or more repetitions of characters in the class. These
repetition items always match the longest possible
sequence.
A single character class
followed by a ?
Zero or one occurrence of a character in the class. This will
always match one occurrence if it is possible to do so.
Chapter 6 Lua Standard Libraries 101
PATTERN MATCHES
%n For nbetween 1and 9; matches a substring equal to the
nth captured string (see the section later in this chapter on
captures).
%bxy,wherexand y
are two distinct
characters
Strings that start with x, end with y, and where the xand y
are balanced. This means that if you read the string from
left to right, counting +1foranxand -1 for a y, the ending
yis the first y where the count reaches 0. For instance, the
item %b() matches expressions with balanced parentheses.
These pattern items can be very simple to use when you need to match a
specific part of a string in a very general way. Table 6-6 gives a number of
example patterns and the corresponding matches when run against the string
“abc ABC 123 !@# \n \000 %“.
Table 6-6: Example Patterns
PATTERN STRING MATCHED
%a a
%a* abc
%a+ abc
%a- no string matched
%a-%s abc
%a? a
%ba3 abc ABC 123
Pattern Captures
A pattern can contain sub-patterns enclosed in parentheses, called captures.
When a match succeeds, the part of the pattern enclosed in parentheses is
stored (captured) for future use. Captures are numbered according to the
order of their left parenthesis because they can be nested. For instance, in the
pattern “(a*(.)%w(%s*))“, the part of the string matching “a*(.)%w(%s*)“
is stored as the first capture (with number 1); the character matching “.“ is
captured as number 2, and the part matching “%s*“ has number 3.
Additionally, the empty capture () captures the current string position
(a number). For instance, if you apply the pattern “()aa()“ on the string
“flaaap“, there will be two captures, the number 3 and the number 5.
102 Part I Learning to Program
Pattern Anchors
A pattern is quite literally a sequence of characters to be matched. Using ˆat
the beginning of a pattern can match the beginning of a string, whereas using
$at the end of a pattern can match the end of a string. When used anywhere
else in the pattern, these strings will match their literal equivalent. Anchors
canbeusedtomakeapatternmoreexplicit.
Pattern Examples
Table 6-7 illustrates a number of common requirements for pattern matching
and shows what that pattern might look like. These are general examples and
mayonlyworkinspeciccases.
Table 6-7: Example Patterns
REQUIREMENT PATTERN
Match a non-space token in a string. “%S+“
Match a string beginning with the text MYADDON:
followed by at least one character, capturing the rest of
the string.
ˆMYADDON:(.+)“
Match a number, optionally with a fractional part after a
decimal point, capturing the entire number. The number
can be positive or negative.
“(%-?%d+%.?%d*)“
Match an assignment in the form xxxx=yyyy, where xxxx
is alphanumeric and yyyy contains no spaces, and
capture each individually.
“(%w+)=(%S+)“
Match a single quoted string, such as 'foo' and 'bar'.“%b’’“
Match the last nonspace token in a string. “%S+$“
Pattern Matching Functions
Lua provides four functions that accept pattern strings:
string.gmatch(s, pattern)
string.gsub(s, pattern, repl [, n])
string.match(s, pattern [, init])
string.find(s, pattern [, init [, plain]])
Chapter 6 Lua Standard Libraries 103
These functions are also available as object-oriented method calls on the
string itself, as with the utility functions discussed earlier. Each of them
accomplishes a different task for strings, as you’ll see.
string.gmatch(s, pattern)
The string.gmatch(s, pattern) function returns an iterator function that,
each time it is called, returns the next set of captures from pattern over string s.
If pattern specifies no captures, the entire match is produced in each call.
For example, the following loop iterates over all the words from string s,
printing one per line:
> s = “hello world from Lua“
> for word in string.gmatch(s, “%a+“) do
>> print(word)
>> end
hello
world
from
Lua
And here’s an example that collects all sets of key=value pairs from the
given string into a table:
>t={}
> s = “from=world, to=Lua“
> for k, v in string.gmatch(s, “(%w+)=(%w+)“) do
>> t[k] = v
>> end
> for k,v in pairs(t) do
>> print(k, v)
>> end
to, Lua
from, world
When working with string.gmatch(), remember that the pattern is
designed to potentially match more than one occurrence, so the pattern
shouldn’t be anchored too heavily (in particular, using the ˆand $anchors
would make the preceding example work incorrectly).
string.gsub(s, pattern, repl [, n])
The string.gsub(s, pattern, repl [, n]) function returns a copy of sin
which all (or the first n, if given) occurrences of the pattern have been replaced
by a replacement string specified by repl, which may be a string, a table, or a
104 Part I Learning to Program
function. string.gsub() also returns as its second value the total number of
matches that occurred.
If repl is a string, its value is used for replacement. The character %works
as an escape character: any sequence in repl of the form %n,withnbetween
1 and 9, stands for the value of the nth captured substring (see the following
example). The sequence %0 stands for the whole match. The sequence %% stands
for a single %.
If repl is a table, the table is queried for every match, using the first capture
as the key; if the pattern specifies no captures, the whole match is used as
the key.
If repl is a function, this function is called every time a match occurs, with
all captured substrings passed as arguments, in order. If the pattern specifies
no captures, the whole match is passed as the argument.
If the value returned by the table query or by the function call is a string or
a number, it is used as the replacement string; otherwise, if it is false or nil,
there is no replacement (that is, the original match is kept in the string).
Herearesomeexamples:
> print(string.gsub(“hello world“, “(%w+)“, “%1 %1“))
hello hello world world, 2
> print(string.gsub(“hello world“, “%w+“, “%0 %0“, 1))
hello hello world, 1
> print(string.gsub(“hello Lua“, “(%w+)%s*(%w+)“, “%2 %1“))
Lua hello, 1
> lookupTable = {[“hello“] = “hola“, [“world“] = “mundo“}
> function lookupFunc(pattern)
>> return lookupTable[pattern]
>> end
> print(string.gsub(“hello world“, “(%w+)“, lookupTable))
hola mundo, 2
> print(string.gsub(“hello world“, “(%w+)“, lookupFunc))
hola mundo, 2
string.match(s, pattern [, init])
The string.match(s, pattern [, init]) function looks for the first match of
pattern in the string s. If it finds one, the match returns the captures from the
pattern; otherwise, it returns nil.Ifpattern specifies no captures, the whole
match is returned. A third, optional numerical argumentinit—species
where to start the search; its default value is 1and may be negative.
string.find(s, pattern [, init [, plain]])
The string.find(s, pattern [, init [, plain]]) function looks for the
first match of pattern in the string s. If it finds a match, find returns the indices
of swhere this occurrence starts and ends; otherwise, it returns nil.Athird,
Chapter 6 Lua Standard Libraries 105
optional numerical argumentinitspecifies where to start the search; its
default value is 1 and may be negative. A value of true as a fourth, optional
argument, plain, turns off the pattern matching facilities, so the function
does a plain ‘‘find substring’’ operation, with no characters in pattern being
considered ‘‘magic.’’ Note that if plain is given, init must also be given.
If the pattern has captures, then in a successful match the captured values
are also returned, after the two indices.
Math Library
The math library provides an interface to several standard math functions and
constants. Table 6-8 describes some of the more common functions in the math
library. (It is not a full listing of the library; for that, please consult a proper
Lua reference, which includes a full set of trigonometric functions such as
math.cos, math.sin, math.tan, and so on.)
Table 6-8: Math Functions
FUNCTION DESCRIPTION EXAMPLE
math.abs(x) Returns the absolute
value of x.
> print(math.abs(13))
13
> print(math.abs(-13))
13
math.ceil(x) Returns the smallest
integer larger than or
equal to x.
> print(math.ceil(1.03))
2
> print(math.cell(13))
13
> print(math.cell(17.99))
18
math.deg(x) Returns the angle x
(given in radians) in
degrees.
> print(math.deg(math.pi))
180
> print(math.deg(math.pi * 2.5))
450
math.exp(x) Returns the value of the
mathematical constant
eraisedtothexpower.
> print(math.exp(27))
532048240601.8
math.floor(x) Returns the largest
integer smaller than or
equal to x.
> print(math.floor(1.03))
1
> print(math.floor(13.0))
13
> print(math.floor(17.99)
17
Continued
106 Part I Learning to Program
Table 6-8: (continued)
FUNCTION DESCRIPTION EXAMPLE
math.fmod(x, y) Returns the remainder
of the division of xby
y, rounding the
quotient toward
zero.
> print(math.fmod(14, 3))
2
> (print(math.fmod(14, 2))
0
math.log(x) Returns the natural
logarithm of x.
> print(math.log(532048240601.8))
27
math.log10(x) Returns the base-10
logarithm of x.
> print(math.log10(10 ˆ2))
2
math.max(x, y,
z, ...)
Returns the maximum
value among its
arguments.
> print(math.max(-13, 7, 32))
32
math.min(x, y,
z, ...)
Returns the minimum
value among its
arguments.
> print(math.min(-13, 7, 32, 17))
-13
math.modf(x) Returns two numbers,
the integral part of x
and the fractional part
of x.
> print(math.modf(10.23))
10, 0.23
> print(math.modf(7/22))
0, 0.31818181818182)
math.pi The value of the
mathematical constant
pi.
> print(math.pi)
3.1415926535898
math.pow(x, y) Returns x raised to the
y power. (You can also
use the expression xˆy
to compute this value.)
> print(math.pow(2, 10))
1024
> print(math.pow(2, -10))
0.0009765625
math.rad(x) Returns the angle x
(given in degrees) in
radians.
> print(math.rad(180))
3.1415926535898
> print(math.rad(180) == math.pi)
true
> print(math.rad(450))
7.8539816339745
math.random([m
[, n]])
Generates
pseudo-random
numbers. The numbers
generated may not be
sufficient for statistical
analysis but provide an
easy way to create
pseudo-randomness in
> print(math.random())
7.8263692594256e-06
> print(math.random(100))
14
> print(math.random(10, 20))
18
Chapter 6 Lua Standard Libraries 107
FUNCTION DESCRIPTION EXAMPLE
a program. For
example, this function
canbeusedalongwith
the
SendChatMessage()
World of Warcraft API
function to allow your
character to make
random sayings based
on certain events.
When called without
arguments, returns a
pseudo-random real
number between 0 and
1 (not including 1).
When called with a
number m, returns a
pseudo-random integer
between and including
1andm. When called
with two numbers m
and n, returns a
pseudo-random integer
between and including
mand n.
math.randomseed
(x)
The pseudo-random
number generator used
by Lua takes an initial
seed and generates a
sequence of numbers
basedonthatseed.As
a result, the same initial
seed will always
produce the same
sequence. This function
has been removed from
the Lua implementation
in World of Warcraft,
but is listed here for
completeness.
> math.randomseed(1000)
> print(math.random(100))
1
> print(math.random(100))
54
> print(math.random(100))
61
> -- reset the seed
> math.randomseed(1000)
> print(math.random(100))
1
> print(math.random(100))
54
> print(math.random(100))
61
math.sqrt(x) Returns the square root
of x. (You can also use
the expression xˆ0.5
to compute this value.)
> print(math.sqrt(169)
13
> print(math.sqrt(2))
1.4142135623731
> print(2 ˆ0.5)
1.4142135623731
108 Part I Learning to Program
NOTE Lua doesn’t include a math.round() function because there are so many
possible variations on what it means to ‘‘round’’ a number. http://lua-users.
org/wiki/SimpleRound shows how to implement the following function, which
rounds a number to a given decimal place:
function round(num, idp)
local mult = 10 ˆ(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
World of Warcraft Additions to Lua
Several functions have been added to the Lua implementation in WoW as
utility functions for developers:
strsplit(sep, str)
strjoin(sep, ...)
strconcat(...)
getglobal(name)
setglobal(name, value)
debugstack([start[, count1[, count2]]])
ThesefunctionsareavailableintheWowLuaaddon,ontheWebLua
webpage, and in the interpreters that are available for download via the
book’s companion website. They may not be available in Lua distributions
obtained elsewhere.
strsplit(sep, str) takes a given string str and splits it into separate
strings on each occurrence of any character in the separator string sep.This
function returns each individual string (with separator characters removed) to
the caller.
> print(strsplit(“:“, “foo:bar:blah“))
foo, bar, blah
> print(strsplit(“ “, “This is a string“))
This, is, a, string
The strjoin(sep, ...) function takes a list of strings and concatenates
them together with the separator string sep, returning the result.
> print(strjoin(“ “, “This“, “is“, “a“, “test“, “string“))
This is a test string
> print(strjoin(“, “, “alpha“, “beta“, “gamma“))
alpha, beta, gamma
The strconcat(...) function takes a list of strings and concatenates them
together into one long string, which is returned.
> print(strconcat(“This“, “is“, “a“, “test“))
Thisisatest
Chapter 6 Lua Standard Libraries 109
> print(strconcat(“alpha:“, “beta:“, “gamma“))
alpha:beta:gamma
getglobal(name) takes a variable name as a string and returns the so-named
global variable, if it exists. This function is deprecated in World of Warcraft,
meaning it should no longer be used but has not yet been removed. It is
included, along with setglobal,incaseyouseeitincodefromolderaddons.
> greek1, greek2, greek3 = “alpha“, “beta“, “gamma“
> for i=1,3 do
>> print(getglobal(“greek“ .. i))
>> end
alpha
beta
gamma
The setglobal(name, value) function takes a variable name as a string,
along with a corresponding value, and sets the so-named global variable to
the new value.
> print(myVariable)
nil
> setglobal(“myVariable“, 17)
> print(myVariable)
17
The debugstack([start[, count1[, count2]]]) function returns the cur-
rent calling stack according to three inputs, as described in Table 6-9.
Table 6-9: debugstack Inputs
INPUT TYPE DESCRIPTION
start Number The stack depth at which to start the stack trace (defaults to 1,
the function calling debugstack)
count1 Number The number of functions to output at the top of the stack
(default 12)
count2 Number The number of functions to output at the bottom of the stack
(default 10)
This function only operates correctly in WoW. The standalone Lua inter-
preter has its own method of providing stack traces.
Function Aliases
In World of Warcraft, many of the library functions have been given shorter
aliases so they are easier to access and type. Table 6-10 contains a full listing of
these aliases.
110 Part I Learning to Program
Table 6-10: Global Aliases
ALIAS ORIGINAL FUNCTION ALIAS ORIGINAL FUNCTION
abs math.abs gsub string.gsub
ceil math.ceil strbyte string.byte
cos math.cos strchar string.char
deg math.deg strfind string.find
exp math.exp strlen string.len
floor math.floor strlower string.lower
frexp math.frexp strmatch string.match
ldexp math.ldexp strrep string.rep
log math.log strrev string.reverse
max math.max strsub string.sub
min math.min strupper string.upper
mod math.fmod foreach table.foreach
rad math.rad foreachi table.foreachi
random math.random getn table.getn
randomseed math.randomseed sort table.sort
sqrt math.sqrt tinsert table.insert
format string.format tremove table.remove
gmatch string.gmatch
Summary
Lua has three major libraries that contain utility functions. The table library
provides ways to insert, remove, and sort array tables; the string library
has a number of useful utilities for tasks such as turning a string into all
lowercase, uppercase, or even reversing the string. In addition to these utility
functions, this chapter introduced the basics of Lua pattern matching and string
formatting using string.format(),string.match(),andstring.find().
CHAPTER
7
Learning XML
As mentioned in Chapter 1, you use two languages to build user interfaces for
World of Warcraft. You have already been introduced to Lua, the programming
language that defines the behavior of the interface, but you haven’t yet tackled
eXtensible Markup Language (XML), used to create the graphical frames that
comprise WoW’s user interface. That’s what this chapter is all about.
XML as a Markup Language
A markup language takes text content and adds extra information to the
document, mixing it in with the text itself. The markup typically describes
something about the text itself, such as the structure of the document or how
the text should be displayed on screen. Following are examples of two notable
markup languages, HTML and LaTeX:
HTML
<html>
<head>
<title>My Document</title>
</head>
<body>
<h1>Heading One</h1>
<p>
This text is <strong>bold</strong>.
</p>
</body>
</html>
111
112 Part I Learning to Program
LaTeX
\documentclass{article}
\title{My Document}
\begin{document}
\maketitle
\section{Heading One}
This text is \textbf{bold}.
\end{document}
Each of these examples provides basic information about the structure of the
content by creating new headings and sections, and delimiting the actual body
of the document. In addition, the <strong> and \textbf{} tags are intermixed
with the text to indicate that a specific word should be displayed in a bold
face font.
XML’s Relationship to HTML
Whereas HTML is a markup language describing presentation with a minimal
amount of structural information, XML is entirely a structural language,
describing the relationship between elements but providing no cues about
how they should be presented. Consider this example XML document:
<addressbook name=“Personal“>
<entry>
<firstname>Alice</firstname>
<lastname>Applebaum</lastname>
<phone>+1-212-555-1434</phone>
<address>
114 Auburn Street
Apt 14
Atlanta, GA
</address>
</entry>
</addressbook>
Unlike the earlier HTML example, this has no presentation cues, and
most applications wouldn’t know how to display this information. An XML
document typically structures information according to some set of rules (such
as a schema definition, which you will explore later this chapter). In short,
XMLisacousinoftheHTMLstandardthatisgeneralizedformultipleuses,
and is stricter in its syntax and structure.
Components of XML
XML is designed to be both human-readable and computer-readable, so it
has a strict required structure. An XML document includes tags, elements,
attributes, and entities, each of which is discussed in the following sections.
Chapter 7 Learning XML 113
XML Tags
An XML tag is an identifier that begins and ends with angle brackets, such
as <tag>. The tags are case-sensitive, so <Tag> is a different tag name than
<tag>. A closing tag is the same as an opening tag, but has a forward slash
immediately after the open bracket, such as </tag>. The XML standard doesn’t
define any specific tags, only the rules defining how and when tags should
appear.
XML Elements
Elements are the lowest level of structure and content in an XML document,
taking some content and enclosing it in a set of open/close tags. A basic
element from the earlier XML example is the <entry></entry> section, which
defines an XML element with the name entry. An XML element can contain
any type of content, including more markup. Elements are governed by the
following rules:
A nonempty element must begin with an opening tag and end with a
closing tag.
An element with no content can either be delimited with start/end tags
or be a self-closing tag. A self-closing tag has a forward slash immediately
before the closing angle bracket, such as <tag /> or <tag/>.
Again, the XML standard doesn’t really define any element types or tags,
but merely describes how the document should be structured so it conforms
to the standard.
XML Attributes
In addition to containing generic content, each XML element can have any
number of attributes, which are named values belonging to that element. An
attribute is declared in the start tag (or the self-closing tag, if used) like this:
<tag attribute=“value“></tag>
Attributes can have any name, but the XML standard requires that all values
be quoted using either balanced single quotes or balanced double quotes. This
ensures that any program conforming to the XML standards can parse the
document.
Unlike an element’s content, which describes more of a parent/child rela-
tionship, attributes describe something specific about the element, such as the
name of the element. The addressbook element has the name Personal,soit
can be distinguished easily from any other addressbook that has been defined.
The distinction isn’t made through the XML standard but is extremely useful
when parsing and validating an XML document.
114 Part I Learning to Program
XML Entities
The XML specification forbids the ampersand (&) and the less-than sign (<)
from appearing within an element. In addition it might be confusing to see
single quotes (), double quotes () and the greater than sign (>)inadocument.
To compensate for this, XML provides a number of escaped entities that can
be included in the place of these characters. Table 7-1 shows a list of the most
common XML entities:
Table 7-1: XML Entities
CHARACTER EQUIVALENT ENTITY
& &amp;
< &lt;
> &gt;
“ &quot;
’ &apos;
Creating Well-Formed XML
A well-formed XML document is one that is valid and parsable from a
syntactic point of view; that is, it follows all the required rules defined by the
standard. Before jumping into the rules for a well-formed document, look at
the definitions of root and non-root elements:
Root element: A root element is an element that is not nested within
another element. The first element in an XML file is the only root element.
Non-root element: An element that is nested within another element.
For a document to be well formed, it must comply with the following:
Any non-empty elements begin with a start tag and end with an end tag.
Empty elements may either be delimited with start and end tags or be
marked as a self-closing element.
All attribute values are quoted with balanced single or double quotes.
Tags may be nested, but must not overlap. In particular, each non-root
element must be contained entirelywithin another element. This disallows
something like <b>Some <i>Text</b></i>,becausethe<i> element is not
contained entirely within another element.
Checking the syntax of an XML document can be as simple as opening it
in your favorite web browser, although more specialized tools are available.
Most modern browsers are XML-capable and can tell you which line of the
Chapter 7 Learning XML 115
document failed. In addition, you can use the XMLValidate utility on the
book’s web page (http://wowprogramming.com/utils/xmlvalidate.) to see
whether your document is well formed.
Validating an XML Document
The XML format itself describes the syntax of the languagethat is, the
rules that make an XML document well-formedbut doesn’t delve into the
semantics, such as what attributes can belong to a given element, and what
relationships can exist between given elements.
One method of describing the semantics of a given XML document is a
schema definition. These definitions can come in a few forms, such as:
Document Type Definition (DTD), a format native to XML.
XML Schema, a W3C standard for declaring a schema.
RELAX NG, a simple schema language available in XML formats as well
as a shorter version.
World of Warcraft defines its schema using the XML Schema standard. The
following section of the chapter focuses on this standard, and how to read it
and use it for validating your files.
Example Schema Definition
The following is a simple XML Schema definition for an address book:
<xs:schema
xmlns:xs=“http://www.w3.org/2001/XMLSchema“>
<xs:element name=“addressbook“ type=“AddressBook“/>
<xs:complexType name=“AddressBook“>
<xs:sequence>
<xs:element name=“name“ type=“xs:string“/>
<xs:element name=“phone“ type=“xs:string“/>
<xs:element name=“address“ type=“xs:string“/>
</xs:sequence>
</xs:complexType>
</xs:schema>
The initial line is standard for declaring a schema; it simply points to the
standard document for the W3C definition of the XML Schema definition.
The second tag defines a new element named addressbook,creatinganew
<addressbook> tag, and associating it with the named type AddressBook.The
rest of the sequence defines what it means to be of type AddressBook,namely
a sequence of four different named elements that is simply string content.
116 Part I Learning to Program
Example XML Document
The following is a file that declares its schema to exist in the file
addressbook.xsd. Assuming both files are in the same directory, this file can
be validated against the schema directly:
<addressbook
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:noNamespaceSchemaLocation=“addressbook.xsd“>
<name>Alice Applebaum</name>
<phone>+1-212-555-1434</phone>
<address>
114 Auburn Street
Apt 14.
Atlanta, GA
</address>
</addressbook>
You can use a number of utilities to validate an XML schema on different
platforms:
XMLNanny (MacOSX), www.xmlnanny.com
Microsoft Visual Studio (Windows), www.microsoft.com/express
XMLSpy, www.altova.com/xml-editor
Decision Soft’s Online XML Validator, http://tools.decisionsoft.com/
schemaValidate
Figure 7-1 shows this XML document being validated against the
given schema using XMLNanny. In addition to these downloadable tools
there is a very simple web-based validator that you can use at http://
wowprogramming.com/utils/xmlvalidate.
The document passes the validation step because it’s been structured
correctly and the schema has been followed exactly. As a matter of fact,
the example schema requires the elements of <addressbook> to appear in the
exact order shown. If you were to swap the order of <name> and <phone>,
the document would no longer validate. To add the elements in any order,
as long as you include them all, you can change the <xs:sequence> and its
matching close tag to read <xs:all>.
Exploring the Schema
One advantage of a strict markup like XML being used for layout is that all
the information necessary to write complex layouts is contained within the
schema itself. The schema reveals to you all of the valid options for any given
tag or attribute. In addition, a number of tools are available to make it easier
for you to edit XML files.
Chapter 7 Learning XML 117
Figure 7-1: Validating with XMLNanny
For example, XMLSpy, Visual Studio, and other XML editors can provide
auto-complete when you’re creating a new file, so attribute names are auto-
matically completed, and some editors even give you dropdowns to select the
values when they are defined.
XML in World of Warcraft
The WoW user interface has an incredibly detailed XML schema that dictates
exactly what tags, attributes, and values are valid when defining frames. To
better understand how everything is structured, you can unpack the latest
XML schema following the directions given in Chapter 8. It will extract to the
Blizzard Interface Data (enUS)/FrameXML/UI.xsd file under your WoW
installation, where enUS is your locale. Here’s an excerpt from the file:
<xs:simpleType name=“ORIENTATION“>
<xs:restriction base=“xs:NMTOKEN“>
<xs:enumeration value=“HORIZONTAL“/>
<xs:enumeration value=“VERTICAL“/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name=“ColorFloat“>
<xs:restriction base=“xs:float“>
<xs:minInclusive value=“0.0“/>
118 Part I Learning to Program
<xs:maxInclusive value=“1.0“/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name=“ColorType“>
<xs:attribute name=“r“ type=“ColorFloat“ use=“required“/>
<xs:attribute name=“g“ type=“ColorFloat“ use=“required“/>
<xs:attribute name=“b“ type=“ColorFloat“ use=“required“/>
<xs:attribute name=“a“ type=“ColorFloat“ default=“1.0“/>
</xs:complexType>
<xs:complexType name=“GradientType“>
<xs:sequence>
<xs:element name=“MinColor“ type=“ColorType“/>
<xs:element name=“MaxColor“ type=“ColorType“/>
</xs:sequence>
<xs:attribute name=“orientation“ type=“ORIENTATION“ default=“HORIZONTAL“/>
</xs:complexType>
This excerpt from the WoW XML schema defines a series of types that are
used later in the schema, along with attributes and valid values. The first
block defines a new type called ORIENTATION. This value is an enumeration,
which means it must be one of the listed values, specifically HORIZONTAL or
VERTICAL.
The second block defines a new type called ColorFloat,whichmustbea
floating-point number. In this case, it must be between the values 0.0 and
1.0 inclusive. Next, a complex type called ColorType is defined; it has three
required attributes and one optional attribute. Any element of this type must
supply values for r,g,andb(which must conform to the rules for ColorFloat),
and may optionally provide a value for a. These correspond to the red, green,
blue, and alpha values of a given color.
Finally, a complex type GradientType is defined; it takes exactly two items
in sequence, a <MinColor> tag and a <MaxColor> tag, both of type ColorType.
Additionally, this tag can take an orientation attribute, described earlier.
Using a GradientType
Assuming there is a <Gradient> tag with the type GradientType defined
somewhere, the following would be a valid usage of this schema:
<Gradient orientation=“VERTICAL“>
<MinColor r=“1.0“ g=“0.0“ b=“0.3“ a=“1.0“/>
<MaxColor r=“0.0“ g=“0.0“ b=“0.0“ a=“1.0“>
</Gradient>
Chapter 7 Learning XML 119
When used as part of a texture in the game, this appears as a gradient from
red to black, with the gradient traveling vertically. This is exactly how the
<Gradient> tag should be used.
Exploring Blizzard’s XML User Interface
Customization Tool
Blizzard has provided us with a tool to extract the XML files that comprise
the default user interface. To extract it, you must download the User Interface
Customization tool from http://www.worldofwarcraft.com/ui.Thiswebsite
contains versions for Microsoft Windows as well as for Mac OS X. Once you’ve
downloaded the file, extract the program and run it. On loading, you’ll see the
screen shown in Figure 7-2.
You have two options:
Install Interface DataExtracts all of the code that defines the default
user interface, the XML schema that defines the markup, as well as two
tutorial addons with step-by-step descriptions.
Install Interface ArtExtracts all the graphics files that are used in the
default interface, such as icons, border textures, and so on.
If you choose to extract the interface data, the following two subdirectories
will be created in your World of Warcraft directory:
Blizzard Interface Data (enUS)
Blizzard Interface Tutorial
If you extract the interface art, the following subdirectory is created:
Blizzard Interface Art (enUS)
You may find that your directories extract with a different directory name.
The enUS in the example stands for U.S. English, the language that the interface
files use. If you use a German WoW client, you may instead see deDE, for
example. You learn more about localization a little later in the book.
The Blizzard Interface Data directory contains two subdirectories,
FrameXML and AddOns. The files contained in FrameXML are loaded
each time the client starts, whereas the files in the AddOns directory are
loaded under certain circumstances (see the listing in Chapter 1 for more
information).
120 Part I Learning to Program
Figure 7-2: User Interface Customization tool
BLIZZARD INTERFACE ART
Although Blizzard provides a way to extract the art that is used throughout
the game, the graphics files are in a proprietary format called BLP2. Blizzard
uses that format for its graphics and, unfortunately, no official tools have been
released to support it.
Foxlit, an enterprising member of the user interface community, has
written a web page that can convert these files on demand, and we have
the opportunity to host a version of it on the book’s companion website:
http://wowprogramming.com/utils/blp2png.
Simply upload a BLP file that you’d like converted, and the web page will
return a PNG image that can be saved and edited. Remember, however, that
World of Warcraft only loads BLP and TGA files, so you’ll have to convert it to
TGA after making any changes.
Alternatively, you can browse the contents of the interface art directories
online at http://wowprogramming.com/utils/artbrowser. Each of the
images are hosted in PNG format for you to view and download.
Chapter 7 Learning XML 121
Summary
XML is a broad specification that allows virtually endless combinations of
schemas and structure, but when dealing with World of Warcraft, you focus
on a very particular subset defined by the schema. The default user interface
uses XML for all of its frame layout and creation, and you can take advantage
of this by using Blizzard’s own code to learn more about the system.
Part
II
Programming in World
of Warcraft
In This Part
Chapter 8: Anatomy of an Addon
Chapter 9: Working with Frames, Widgets, and Other Graphical Elements
Chapter 10: Saving Time with Frame Templates
Chapter 11: Exploring the World of Warcraft API
Chapter 12: Interacting with Widgets
Chapter 13: Responding to Game Events
Chapter 14: Tracking Damage with CombatTracker
CHAPTER
8
Anatomy of an Addon
As discussed in Chapter 1, an addon for World of Warcraft is a collection of text
and media files packaged together and loaded to extend the core functionality
of the game client. At the more virtual level an addon is also a collection of
functions, tables, frames, textures, and font strings.
This chapter explains the contents of an addon’s files, and introduces you to
the widgets system and the event-based programming system used in WoW.
Exploring an Addon’s Files and Folders
An addon consists of a table of contents file that defines certain metadata about
an addon (such as name, author, version, and a list of files to be loaded), along
with XML frame definitions, Lua scripts, and other media files. This section
details the actual contents of these files.
Table of Contents (.toc) File
The one file that must be included in every addon is the table of contents
(TOC) file, which must have the same name as the addon’s directory. For
example, if an addon’s directory name is MyAddon, it must contain a file
called MyAddon.toc. The TOC file provides vital information about the addon
(such as title, description, author, and so on) along with a list of files to be
loaded by the game client. A sample .toc file might look like this:
## Interface: 30300
## Title: My Addon Name
125
126 Part II Programming in World of Warcraft
## Author: My Name Here
## Notes: This is my sample addon
MyAddon.xml
MyAddon.lua
Each line beginning with ## contains a definition of some sort of metadata.
For example, the ## Title metadata is displayed on the addon selection
screen, and ## Notes contains a longer description that is displayed when you
mouse over the addon in that list. The lines after the directives are simply a
list of files to be loaded by the addon.
## Interface:
## Interface: 30300
The interface version directive (## Interface: 30300 in this example)
provides a basic versioning mechanism that the client uses for the addon
selection screen. The game client uses this number to verify that an addon is
compatible with the current game version. If the version is not compatible, the
game will label it with one of two states:
Out of dateThis state indicates that there has been a patch to the game
client since the addon was written. This is strictly just a warning; the
addons may work just fine if you check ‘‘Load out of date AddOns’’ at
the top of the screen. The version number typically only changes when
there is an actual change to the API, so this warning should be heeded.
IncompatibleWhen a major change happens to the game client (such
as an expansion pack), the addon selection screen will display this status
and will refuse to load the addon. A new version of the addon should be
downloaded to ensure it operates correctly in the new API.
Figure 8-1 shows two addons, one flagged as out of date and the other
as incompatible. TinyPad could be loaded by checking the Load out of date
AddOns checkbox, but nothing can force the incompatible addon to load.
Figure 8-1: Addon selection screen
Just because an addon is listed as out of date doesn’t mean there’s anything
particularly wrong with it, only that the game client has been patched since the
Chapter 8 Anatomy of an Addon 127
.toc file was last updated. When that happens, it’s a good reminder to update
your addons and make sure you’re using the latest versions. This helps you
get the latest bug fixes and features, and also makes it easier for the author of
the addon to support you.
The interface number is generally built from the version number of the
WoW client. For example, the interface number for the 3.3.0 client is 30300.
However, this does not necessarily change each time there is a patch. If after
a WoW patch you’re not sure what interface number to use in building your
own addons, you can extract the latest FrameXML files using the User Interface
Customization Tool introduced in Chapter 7 and consult the FrameXML.toc file.
ADDON SELECTION SCREEN
You can access the addon selection screen by clicking the AddOns button at
the bottom-left of the character selection screen. This button appears when
you have downloaded and installed an addon in the appropriate place.
From the selection screen, addons can be enabled and disabled on a
per-character or global basis. The global settings work only for a single server,
so if your characters are on different servers, you will need to configure them
independently. The addon selection screen can be used to browse the addons
that are available on a given system, as well as any dependencies they may
have.
When things go wrong with an addon, checking the addon selection screen
to ensure the addon isn’t flagged as ‘‘Out of date’’ or ‘‘Incompatible’’ is a good
place to start to ensure the addon is actually being loaded.
## Title:
## Title: Hello Friend
When addons are listed in the addon selection screen, they are sorted and
shown by their ## Title directive, rather than by the name of the addon’s
TOC file or directory. This can be somewhat confusing as you try to determine
which directory corresponds to which addon title in game, but these problems
are relatively infrequent and easy to resolve. The default value for this option
is the name of the addon’s directory.
The ## Title directive can be localized, meaning it can display different
text depending on which language the user’s client is set to display. To localize
it for Spanish language users, for instance, you’d add a hyphen followed by a
locale code, such as ## Title-esES: Hola Amigo. When your addon is loaded
on a WoW client with that locale, the custom name will be displayed instead
of the generic one supplied in the ## Title directive. Localization of addons
is covered in more depth later in this chapter.
128 Part II Programming in World of Warcraft
## Notes:
## Notes: Greet other players
The ## Notes directive gives you the capability to provide a longer descrip-
tion of your addon. This field can also be localized to provide a different
description depending on client locale in the same way as ## Title,andmay
also contain color codes to highlight portions of the text. Figure 8-2 shows the
tooltip displayed by the WoWLua addon .toc file.
Figure 8-2: WowLua tooltip, generated from ## Title and ## Notes directives
## Dependencies:, ## RequiredDeps:
## Dependencies: Juggernaut, Alpha
## RequiredDeps: Juggernaut, Alpha
Occasionally, one addon requires another to be loaded in order to function.
For example, certain addons are organized into individual addon plugins, all
requiring one central addon. To express this, you give the ## Dependencies or
## RequiredDeps directive a list of comma-separated addon names. The game
client will load all required dependenciesofanaddonbeforetryingtoload
the addon itself.
When an addon is missing a required dependency, or the dependency addon
has been disabled, an error message is displayed, as shown in Figures 8-3
and 8-4. You can move your mouse over the addon name to view a list of
dependencies and see which ones are missing.
Figure 8-3: Addon with dependency disabled
Figure 8-4: Addon with dependency missing
Chapter 8 Anatomy of an Addon 129
Dependencies also ensure addons are loaded in the proper order, so if Beta
relies on Alpha, the client will load Alpha before it loads Beta. This is even
true for a long chain of dependencies. ## Dependencies and ## RequiredDeps
both work the same for this directive. Addons should obviously try to avoid
circular dependencies, because no addon will ever be loaded in that case.
## OptionalDeps:
## OptionalDeps: Juggernaut, Alpha
When an addon can interact with another addon, but doesn’t strictly require
it to function, it can be listed as an optional dependency using the ##
OptionalDeps directive. All this directive does is ensure that the optional
dependencies are loaded before this addon, if they are available. This directive
takes a comma-separated list of addon names. The names listed must match
the .toc file and the directory names of the given addons.
## LoadOnDemand:
## LoadOnDemand: 1
As mentioned in Chapter 1, each of the Blizzard addons is configured to
load on demand, meaning that the client will load and initialize the addon
in response to some game event. This saves memory and load time by not
loading all of the addons each time the player logs in to the game, but only
when he needs them. Because not all addons may be written in a way that
supports load on demand (LoD), there is a directive that flags an addon as
LoD capable.
An LoD addon can still use the other directives, and still appears in the
addon list, but will not be loaded until explicitly requested by another addon.
Many addons use this functionality for their configuration systems, only
loading them when the user tries to make a configuration change.
This option takes either a 1or a 0,where1means the addon is LoD capable,
and 0means it is not. If this value isn’t supplied in the TOC, it defaults to 0.
## LoadsWith:
## LoadsWith: Blizzard_RaidUI
The ## LoadsWith directive can be combined with ## LoadOnDemand to load
an addon as soon as another is being loaded. For example, an addon that alters
the default Blizzard Raid UI could include ## LoadsWith: Blizzard_RaidUI
to be loaded along with the default raid interface. This directive has rather
limited use but expands the usefulness of LoD components quite a bit. If
130 Part II Programming in World of Warcraft
multiple addons are listed, the addon will be loaded as soon as any of those
listed finishes loading.
## DefaultState:
## DefaultState: disabled
Not all addons are meant to be loaded on each and every character, so this
directive enables you to set the default state of an addon. The flag tells the
client whether an addon should be checked (enabled) in the addon selection
screen by default. As soon as a user overrides this setting by checking or
unchecking the addon, the user preference is respected. If not supplied, this
value defaults to enabled.
## LoadManager:
## LoadManager: AddonLoader
Adding to the complexity (and versatility) of the LoD system is the ##
LoadManager directive, which indicates that some other addon will take respon-
sibility for loading this addon. The addon is flagged as LoD as long as the load
manager addon is installed and enabled.
The most prevalent load manager is called AddonLoader and is available
from a few different locations, including:
http://wowace.com/projects/addon-loader
http://wowinterface.com/downloads/info11476-r77-release.html
AddonLoader is used by several addons as a LoadManager. The developer
can provide conditions in the TOC that AddonLoader then uses to decide
when the addon should be loaded. For example, an addon that is specific to
Rogues can be flagged with ## X-LoadOn-Class: Rogue, and it will be loaded
for any rogue characters but not for any others.
This method requires the developer to add these flags to the TOC file and
the user to download AddonLoader, but it provides major benefits when used
correctly. You can find documentation about using AddonLoader online at
http://www.wowwiki.com/AddonLoader.
## SavedVariables:
## SavedVariables: JuggernautDB
The only way an addon can save information between sessions is to define
a Lua variable and list the name of the variable in the ## SavedVariables
directive in its TOC file. This tells the game to save the contents of that variable
out to a file when the game is closed, and read it back in when the game is
started up again. The variable can be a string, number, Boolean, or table.
Chapter 8 Anatomy of an Addon 131
## SavedVariablesPerCharacter:
## SavedVariablesPerCharacter: JuggernautDB
The ## SavedVariablesPerCharacter: VariableName directive operates in
the same way as ## SavedVariables:, except a different file is saved and
loaded for each character you log in with. If you log in to character Alice, her
settings will be saved separately from those for Bob. Nothing special needs to
happen in the addon; it’s all handled automatically by the client.
NONSTANDARD METADATA DIRECTIVES
Beyond the officially supported metadata tags, you may see any number of
other tags included in the .toc file of custom addons. One customary direc-
tive is ## Author. This information isn’t displayed by default client, but can be
accessed by other addons in-game.
## Author: ArgyleSocks
X-Label Directives
In addition, custom directives can be defined with an X, followed by a hyphen
and then some label. These directives can contain any string of data, limited to
roughly 1,000 characters. For example, an addon could include a web address
using an ## X-Website directive.
Each of the X label directives is localized by the game client, so you can
include all of the following and only the correct version will be available
through the GetAddOnMetadata() API function:
## X-FAQ-Website: http://www.myaddon.com/faq/
## X-FAQ-Website-esES: http://www.myaddon.com/faq/esES
## X-FAQ-Website-deDE: http://www.myaddon.com/faq/deDE
Addon Categories
The addon community has developed a standard set of addon categories that
can be included in the metadata for an addon, making it easier to group simi-
lar types of addons together when listing or displaying them. Here’s the list of
categories:
Action Bars Frame Modification Priest
Auction Guild Quest
Audio Healer Raid
Battlegrounds/PvP Hunter Rogue
(continued)
132 Part II Programming in World of Warcraft
NONSTANDARD METADATA DIRECTIVES (continued)
Buffs Interface Enhancements Shaman
Caster Inventory Tank
Chat/Communication Library Tradeskill
Combat Mage UnitFrame
Compilations Mail Warlock
Data Export Map Warrior
Development Tools Miscellaneous
Druid Paladin
You could use one of these categories or define your own set that’s
the beauty of addon metadata. To supply your category, simply use the ##
X-Category: CategoryName directive.
XML Files
HelloFriend.xml
A table of contents file can list any number of XML files to be loaded.
Markup in these files will be validated against the WoW UI XML schema file
as it’s parsed and loaded. XML files can also load Lua scripts using the <Script
file=“SomeFile.lua“/> tag. Each XML file should contain a top-level <Ui>
element.
To validate your XML document, you will also need to include the schema
information in the <Ui> element. Here’s an example:
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
This may need a bit of explanation. The xlmns attribute defines the name-
space that the document is hoping to conform to. It must match the namespace
declared in the given schema. In this case, it is a value defined by Blizzard. The
xmlns:xsi attribute tells the validating program to which schema instance the
schema will conform. Finally, xsi:schemaLocation is a pair of strings, the first
being the name of a namespace and the second being the location where that
schema can be found.
The example specifies that the http://www.blizzard.com/wow/ui/ schema
can be found in the online document http://wowprogramming.com/FrameXML/
UI.xsd. This is a file that is kept updated on the website for validation
purposes. Instead of using the online version, you could specify the path to
the UI.xsd file on your local machine. The location of this file depends on your
specific installation, but it will be unpacked when you use the User Interface
Customization Tool.
Chapter 8 Anatomy of an Addon 133
As your XML files are loaded, any errors will appear in the Logs\
FrameXML.log file in your base World of Warcraft installation. If your addons
aren’t behaving properly, it’s a good idea to check this file to ensure there
wasn’t an error in validating or parsing your code.
Lua Script Files
HelloFriend.lua
The TOC file can list any number of Lua files that exist somewhere under-
neath the addons directory. Each of these files is loaded, parsed, and then
executed by the game client in the order listed in the TOC file. Because each file
is run independently, local variables defined in one file will not be available
in another file; if you need to share data between different files you should
ensure that you use global variables of some sort.
Media Files
Addons can include custom graphics, sounds, and fonts to be displayed (or
played) within the game client, providing a different visual style or audio
cues. These files are included within the addon directories themselves, and are
addressed by full pathname from the WoW directory.
Music
Assume you have a file called CreepySound.mp3 included as part of an addon
called Goober that resides in the following location:
World of Warcraft\Interface\Addons\Goober\CreepySound.mp3
It can then be played by running the following command in-game (remember
to escape the backslash character because Lua uses it as the escape character):
/run PlaySoundFile(“Interface\\Goober\\CreepySound.mp3“)
The WoW client can natively play MP3 files as well as WAV files. Converting
files to these formats can be accomplished through a number of tools freely
available on the Internet.
Graphics
WoW accepts two graphics formats when loading textures for frames. In
addition to being in the right format, each graphic must meet the following
basic requirements to be loaded:
1. The file’s width and height must be greater than or equal to 2, and smaller
than 1024 pixels.
2. The height and width of the file must be a power of two, although they
need not be the same.
134 Part II Programming in World of Warcraft
For example, a file that is 32 x 64 is acceptable, whereas a file that is 512 x 400
is not (because the height is not a power of two). In addition, the file can, and
should, contain an alpha channel, something that is particular to the specific
graphics editing software you are using.
More information on creating and editing custom graphics for addons is
available in Chapter 20.
Following is a look at the two primary graphics formats used in WoW: BLP2
and TGA.
BLP2 Format
If you have extracted the Blizzard Interface Art using the User Interface
Customization Tool (as shown in Chapter 7), you may have noticed that all the
files that were created have a .blp extension. That file format was created by
Blizzard, and has been used in both Warcraft III and World of Warcraft. Even
though Blizzard provides a way to extract the files, there is still no official tool
that can convert these files. The companion website for the book provides a
way to convert these graphics to the PNG format, which is easier to view and
edit; see Chapter 7 for more information.
The only time this book deals with .blp files is if any original game art is
altered, in which case the texture is provided in the .tga format instead.
TGA Format
Wikipedia defines a .tga file as a Truevision Advanced Raster Graphics
Adapter (TARGA) file. This is a simple graphics file format that can be used to
store color images, including transparency information. TGA files never use
lossless compression, which means the image is not degraded as a result of
saving the image, as happens with JPG files. Most modern graphics editors can
save to this file format natively, and Chapter 20 provides an extensive tutorial
on creating files to be used in the game.
Localizing Your Addons
Localization as it relates to addon development is the process of converting
the text and icons used in the application to a format that is meaningful for
users from other regions of the world, who may speak different languages.
WoW boasts more than 10 million subscribers, many of them coming from
regions in Europe and Asia. You may see the word ‘‘localization’’ abbreviated
to L10n, which stands for ‘‘L’’ followed by 10 other letters, followed by an
‘‘n.’’ Similarly, you may see I18n as an abbreviation for ‘‘Internationalization.’’
However you call it, localization makes your addons more accessible.
Chapter 8 Anatomy of an Addon 135
Valid Locales
Blizzard provides a number of game locales with World of Warcraft. Table 8-1
shows a list of the current valid game locale codes. For each of these
languages, Blizzard has translated each in-game message and string so they
are meaningful to users from that region.
Table 8-1: Valid Client Locales
LOCALE CODE CORRESPONDING LANGUAGE
deDE German
enUS American English
enGB British English
esES Spanish
esMX Spanish (Mexico)
frFR French
koKR Korean
ruRU Russian
zhCN Simplified Chinese
zhTW Traditional Chinese
Although there is technically an enGB locale, the game will never display
that locale anywhere (in particular, GetLocale() will not return it).
Reasons for Providing Localization
When users play the game in their native language, it’s often easier for them
to make split-second decisions if they aren’t trying to read an entirely different
language as part of a custom addon. Imagine if you were a native Spanish
speaker who played the game in Spanish, but had addons that displayed your
information in English. Even if you’re a fluent reader of both languages, your
brain may find difficulty in switching between the two quickly.
From a purely practical standpoint, why not provide support for localization
in your addon? Most users are willing and able to help authors with the addon
localization, and if the addon is organized well, it can be a very easy task to
keep localizations up to date.
136 Part II Programming in World of Warcraft
Encouraging Users to Contribute
More often than not, users will approach authors with localization files, but
the author can take some steps to ensure the addon is easy to localize. This
typically means the following:
1. Include a dedicated localization le with no other addon logic, including
a set of constants of a lookup table to be used instead of string constants.
2. Provide information in the readme.txt file for your addon and the
addon’s website on how users can contact you to help with localization.
3. Provide comments about what a specific message means so it can easily be
translated. Although the word ‘‘speed’’ means only one thing in English,
it may translate to different words depending on the language.
Implementing Localization
Because localization implementations are simply different means of structuring
Lua programs, there are countless ways to do it. This section describes one
particular way to implement localization.
When working with non-English locales, you should ensure that your
editors work properly with UTF-8 markup. Most modern text editors work
just fine, but older, less-featured editors may show garbage instead of the
correct markup.
Add a File for Each Locale
Begin by adding a new localization file for each locale for which you have
translations. If you don’t have any translations to begin with, simply create a
file for the ‘‘base’’ locale in which you’ve developed the addon. For my addons,
this means adding a Localization.enUS.lua file to my directory structure.
Add the file to the top of the .toc file to ensure that it’s loaded first.
Create a Global Table Containing the Base Strings
Create a new global table called MyAddonLocalization in the Localization
.enUS.lua file, replacing MyAddon with the name of your addon. For instance,
if your addon is named BurgerDoodle, your global table would be called
BurgerDoodleLocalization.
You can use full strings or tokens to add the base translations to this file.
Using Full Strings
The following is a set of table definitions that takes the entire string to be
translated and uses it as both the key and the value. The reason for this will
become apparent later.
Chapter 8 Anatomy of an Addon 137
MyAddonLocalization = {}
MyAddonLocalization[“Frames have been locked“] = “Frames have i
been locked“
MyAddonLocalization[“Frames have been unlocked“] = “Frames have i
been unlocked“
This tends to work for smaller strings but, as you can see, can be quite
verbose for longer string keys.
Using Tokens
Instead of using the entire string as the table key, you can use a smaller string
or ‘‘token.’’ The same localization file might look like this:
MyAddonLocalization = {}
MyAddonLocalization[“FRAMES_LOCKED“] = “Frames have been locked“
MyAddonLocalization[“FRAMES_UNLOCKED“] = “Frames have been unlocked“
Using the Localization Table
The reason for loading the localization file first is to ensure that the tables are
available when the rest of the addon files are loading. For example, you can
display the ‘‘locked’’ message using the following:
print(MyAddonLocalization[“Frames have been locked“])
or
print(MyAddonLocalization[“FRAMES_LOCKED“])
If that appears too verbose for you, you could make a shortcut to the global
table. This is typically done with the variable L, which is used in other software
realms for localization:
local L = MyAddonLocalization
print(L[“Frames have been locked“])
If you’ve opted for the token method, you can even use syntactic sugar to
make it easier to type:
print(L.FRAMES_LOCKED)
Adding New Locales
New languages can be added by defining new files and following the standard
you’ve already established. The new files should be listed after thebaselocale
in the .toc file, but before the main addon. For example, create a localization file
for German by creating Localization.deDE.lua with the following contents:
if GetLocale() == “deDE“ then
if not MyAddonLocalization then
138 Part II Programming in World of Warcraft
MyAddonLocalization = {}
end
MyAddonLocalization[“FRAMES_LOCKED“] = “Frames wurden gesperrt“
MyAddonLocalization[“FRAMES_UNLOCKED“] = “Frames wurden entsperrt“
end
The first line checks to ensure that the user’s locale is deDE; otherwise, the
translation file is skipped. The second line creates the global table if it doesn’t
already exist, and the rest is the same as the base locale file, with the values of
the table being the translated strings.
Now the message printed on a German client will be displayed in the native
language rather than in English.
Handling Partial Translations
What happens if some strings have been translated into German but not others?
Currently, because the main English table is created first, and the German table
is loaded after it, any English strings that haven’t been translated to German
will be displayed in English. This gives you a mix of the two rather than an
error message.
Introducing Frames, Widget Scripts, and Events
Although the previous section explained the different components of addons,
it only covered the details of the files stored on your computer. There’s quite
a bit more to getting an addon up and running. This section introduces you to
the different components that make up an addon within the game.
Frames, FontStrings, and Textures
Every visual component in an addon begins with a frame, which serves as
the container for font strings and textures. A number of types of frames serve
different purposes. For example, the following is a short list of some of the
different frame types (a full listing is given in Chapter 10):
StatusBarUsed to display a numerical value in a given range, such as
health, mana, or a progress bar.
CheckButtonUsed for any button that has an on and an off state, such
as checkboxes or radio buttons.
EditBoxAllows the user to supply input via the keyboard.
ScrollingMessageFrameCan display a series of text messages in a
scrolling frame.
The main differences between the different types are the functions that they
provide to customize them. For example a StatusBar allows you to set the
Chapter 8 Anatomy of an Addon 139
minimum and maximum values for the bar, and the ScrollingMessageFrame
enables you to add and clear messages from the frame.
Most frames by themselves have no actual visible components, but
FontStrings and Textures can be used to add text and graphics to frames.
Displaying Text with FontStrings
AFontString is a special type of object that is dedicated to displaying text.
The following attributes and a number of others can be customized via
XML or Lua:
Font, size, color, outline, and shadow
Justification (both vertical and horizontal)
Whether the text should wrap in the middle of a word
Almost all text that is visible within the UI is a FontString customized in a
specific way, set to display certain text.
Showing Graphics and Colors with Textures
Textures in World of Warcraft serve a similar purpose to font strings, except
for graphics, colors, and gradients, which can be used to display a graphic file
stored on disk, a solid color, or a gradient from one color to another.
Anchoring Objects On-Screen
All object placement in World of Warcraft is accomplished through a series of
anchors that attach one point on an object to one point on another object. The
concepts of anchoring are covered in-depth in Chapter 9.
Responding to Interaction with Widget Scripts
World of Warcraft allows you to respond to user interaction (such as clicking a
button) via widget scripts. These scripts are numerous and varied, depending
on the type of widget being used. Table 8-2 shows a few widget scripts and
their purpose.
Setting these scripts is relatively simple, just a matter of providing a
Lua function to handle the event. Widget scripts are covered in depth in
Chapter 12.
Responding to Game Events
Most of the benefit of using addons is being able to respond to certain
game events (such as entering combat or requesting a duel) and displaying
something to the user. All handling of game events happens through frames.
140 Part II Programming in World of Warcraft
Table 8-2: Widget Scripts
WIDGET TYPE SCRIPT DESCRIPTION
Button OnClick Fires when the user clicks the button, or
when other code calls the button’s Click()
method.
EditBox OnEscapePressed Fires when the escape key is pressed while
the focus is in the edit box.
ScrollFrame OnVerticalScroll Fires when the scroll frame is scrolled
vertically.
Frame OnEnter Fires when the mouse enters the boundaries
of the frame.
Frame OnShow Fires each time the frame is shown (from a
hidden state).
Frame OnEvent Fires when the frame has registered for a
game event, and the event occurs.
To register for a game event, you can call the Frame:RegisterEvent()
method, which accepts the name of the event as a string. Once registered, you
can set the OnEvent widget script to run code when the event fires.
The following code creates a frame (with no display) that prints a message
to your chat frame when you enter and leave combat. (Don’t worry about the
names of the events; you’ll find some of them can be pretty peculiar.) In this
case the event to indicate you are entering combat is PLAYER_REGEN_DISABLED,
because that is when you stop regenerating health.
if not MyCombatFrame then
CreateFrame(“Frame“, “MyCombatFrame“, UIParent)
end
MyCombatFrame:RegisterEvent(“PLAYER_REGEN_ENABLED“)
MyCombatFrame:RegisterEvent(“PLAYER_REGEN_DISABLED“)
function MyCombatFrame_OnEvent(self, event, ...)
if event == “PLAYER_REGEN_ENABLED“ then
print(“Leaving combat...“)
elseif event == “PLAYER_REGEN_DISABLED“ then
print(“Entering combat!“)
end
end
MyCombatFrame:SetScript(“OnEvent“, MyCombatFrame_OnEvent)
That may be confusing right now, but this is just meant to be an introduction
to game events.
Chapter 8 Anatomy of an Addon 141
Loading of an Addon
The loading of an addon can also be somewhat confusing, so this section
shows you the different stages of the loading process.
1. When World of Warcraft is opened, the AddOns directory is scanned
to build a list of addons the user has installed, including their metadata
(metadata will not be reloaded again until you completely close the WoW
client).
2. Player logs in to World of Warcraft and is shown the character selection
screen for a given server.
3. At this point the player can enable and disable addons for either the
currently selected character or for all of the characters on the server.
4. Player selects a character and begins entering the game world.
5. Default user interface XML and Lua files are loaded in the order specified
in FrameXML.toc. This may cause Blizzard addons to load on demand,
depending on the situation.
6. Enabled, non-load-on-demand addons that do not have errors on the
AddOns page are loaded:
a. If this addon is dependent on any other addons and they are not
currently loaded, load them first, in an order that is dependent on the
operating system (some are alphabetic, others are by date created).
b. The addon’s Table of Contents file is read to create a list of files to be
loaded.
c. Each file is processed in order, and any LoadAddon() commands
are processed immediately. Any script elements in XML files are
processed immediately upon encountering them.
d. The saved variables for this addon are loaded (if present from a
previous game session).
e. The ADDON_LOADED event is fired with the first argument set to the
name of the addon that has completed loading. Depending on the load
structure of your addons, the first event you see may not be for your
addon.
7. Blizzard’s saved variables, key binding, and macros begin loading and
synchronizing (this continues in the background).
8. The SPELLS_CHANGED event fires, indicating that the player’s spellbook
has loaded and is available to the user interface.
142 Part II Programming in World of Warcraft
9. The PLAYER_LOGIN event fires indicating that most information about the
game world should be available to the user, and sizing and positioning
of frames should have been completed.
10. The PLAYER_ENTERING_WORLD event fires, indicating that the player has
entered the game world.
At some point after this sequence the VARIABLES_LOADED event should fire,
indicating that Blizzard’s saved variables, macros, and key bindings have been
loaded or synchronized.
Summary
This chapter introduced you to the different components of an addon, both
on your computer and within the game world. You learned about the various
directives that can be included in a table of contents file. The frame and event
system was introduced briefly.
Learning about concepts is well enough, but you’re reading this book to
learn how to actually create addons. The next five chapters will lead you
through creating an addon called BagBuddy for World of Warcraft. Each
chapter introduces you to the details of a specific section of the user interface,
and then you will use those skills to implement a portion of the addon.
Each chapter will build on the code from the previous chapter, so try to
work through the chapters in order. If you do choose to work out of order,
there will be full code listings at the end of each chapter to prevent confusion.
CHAPTER
9
Working with Frames, Widgets,
and Other Graphical Elements
Chapter 8 introduced the concepts of frames, textures, and font strings.
This chapter builds on that introduction, showing you how to create the
foundations for an addon called BagBuddy.
Although the frame definitions in this chapter are written using XML, you
also see how the same effect could be achieved using purely Lua code. XML
is used for this addon because it is helpful to validate against the WoW
XML schema, and it helps separate the frame definitions from the behavioral
code of an addon.
Introducing BagBuddy
Each of the different race and class combinations has its own sets of problems.
One area in which they all have issues is inventory. Items you loot go into the
first free slot in your bags, so while playing your bags can become an unsorted
mess. Countless addons help you sort your inventory, or display it in a more
meaningful way.
The addon you create in this chapter takes a different approach and is meant
to work alongside your inventory. BagBuddy is an extra panel in the user
interface that can filter your inventory by name or rarity, and always displays
results with most-recently-looted first. That way if you need to find something
that you’ve just looted, you can open BagBuddy and it should be displayed at
the top of the list.
143
144 Part II Programming in World of Warcraft
Creating an Addon Skeleton
BagBuddy consists of an XML definition of the frames, and a Lua script
that defines the behavior and logic of the addon. Start by creating a new
directory within your Interface\AddOns folder called BagBuddy. Inside this
new directory create a file called BagBuddy.toc and add the following content:
## Interface: 30200
## Title: BagBuddy
## Notes: A handy helper that allows you to filter your inventory
BagBuddy.lua
BagBuddy.xml
Now create BagBuddy.xml, adding just the basic definition of the <Ui>
element that you have seen before:
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
</Ui>
Finally, create an empty file called BagBuddy.lua. You won’t be adding any
code to it for the next few chapters, but creating it now ensures that the WoW
client will recognize the file without needing to be restarted.
Creating a Frame
The World of Warcraft user interface is based around the central concept of
frames. All textures and font strings must belong to a parent frame. Frames
can register for events and receive notification of game events. In addition, the
user can interact with frames, for example by clicking them. As a result, most
addons begin with a definition of a frame. BagBuddy is no different.
In BagBuddy.xml, add the following code inside the <Ui> element:
<Frame name=“BagBuddy“ parent=“UIParent“>
<Size x=“384“ y=“512“/>
<Anchors>
<Anchor point=“CENTER“ relativePoint=“CENTER“ i
relativeTo=“UIParent“/>
</Anchors>
</Frame>
This code creates a new frame called BagBuddy that is a child of UIParent.
The frame is given a width of 384 and a height of 512, and is anchored to the
center of UIParent, making it appear in the middle of the player’s screen.
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 145
Parenting
Every frame, texture, and font string can have at most one parent, and in fact
textures and font strings are required to have a parent. In addition, a frame
may have any number of child frames. Having an explicit mechanism for
parenting helps define a hierarchy for the user interface:
1. When a parent is hidden, all child frames cease to be visible. If this
weren’t the case, you’d have to manually hide all the other elements that
might be attached to a frame.
2. A frame’s effective scale is defined by multiplying the frame’s scale by its
parent’s effective scale. If the parent is scaled to be larger or smaller, then
all of the children are grown or shrunk by the same amount.
3. A frame’s effective transparency (alpha) value is defined by multiplying
the frame’s alpha by its parent’s effective alpha. This enables you to make
not only a button transparent, but to ‘‘dim out’’ a frame and all of its
children at the same time.
Most of the Blizzard default frames are parented to UIParent.Thisisa
special frame that is used to hide the user interface when the player presses
Alt+Z. In addition, having a single common parent allows the interface to be
scaled consistently, making everything smaller or larger. When creating new
frames, most times you should parent the frames to UIParent at some point
to ensure they work the same as the other frames to which the user may be
accustomed.
When creating frames using XML, parenting also provides you with an easy
to way to name your frames consistently. Any name can include the string
$parent, which is expanded to the name of the parent frame when actually
being loaded.
You have three different ways to set the parent/child relationship between
objects: specifying a parent explicitly using XML attributes, using the hierarchy
of XML elements to define the relationship, or calling the SetParent() method
on an object directly:
Attributes—Use the parent XML attribute to define a parent/child
relationship in an XML frame. This attribute’s value should be the name
of a frame that is to be set as the parent. In the preceding example, this is
used to parent BagBuddy to UIParent. You cannot use this attribute to set
the parent of a texture or font string.
XML hierarchyEach object is by default given a parent simply through
its nested location within the XML file. Although creating sub-frames,
font strings, and textures is covered later in this chapter, you should know
that when defined in XML, a parent/child relationship is automatically
established.
146 Part II Programming in World of Warcraft
The SetParent() methodOnce an object has been created, you can
call the SetParent() method to change the parent. This function takes a
single argument: the frame object of the new parent (not its name).
Giving Objects Sizes
Naturally, before the user interface can know what to do with your objects, it
needs to know how large or small they are. The size of an object can be given
using the <Size> XML element, using either absolute or relative dimensions.
Absolute Dimensions
Absolute dimensions are specific pixel values that define how large an object
will be. In the earlier XML definition for BagBuddy, the frame is set to be
384 units wide by 512 units tall using the size tag:
<Size x=“384“ y=“512“/>
Most of Blizzard’s own XML code uses the following format instead:
<Frame name=“MyFrame“>
<Size>
<AbsDimension x=“384“ y=“512“/>
</Size>
</Frame>
Either method declares the size in the same way. The more compact notation
is generally considered more readable and easier to type.
Relative Dimensions
Instead of using absolute values, a frame can express its height and width as a
percentage of its parent. Consider the following XML snippet that creates two
new frames:
<Frame name=“RelativeExample“>
<Size x=“100“ y=“50“/>
</Frame>
<Frame name=“RelativeExampleChild“ parent=“RelativeExample“>
<Size>
<RelDimension x=“0.5“ y=“0.5“/>
</Size>
</Frame>
The first frame, RelativeExample, has a size in absolute dimensions
(100 units wide by 50 units high), but the second is defined using relative
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 147
dimensions. As a result, RelativeExampleChild will be 50 units wide by
25 units high. You won’t see this method of sizing used very often (as a matter
of fact it’s not currently used in the default interface), but it is still available as
an option.
Anchoring Objects
All object placement in World of Warcraft is done through a series of anchors
that attach one point on a frame to some other point on another frame.
Figure 9-1 shows the nine different anchor points on the frame.
CENTER
TOP
TOPRIGHT
RIGH
T
BOTTOMRIGHT
BOTTOM
BOTTOMLEFT
LEFT
TOPLEFT
Figure 9-1: Available anchor points
In XML, anchors are placed within the <Anchors> element. A frame can
have any number of anchors, each defined using the <Anchor> element with
the following attributes:
pointThe point being anchored. The next section explains what each
of the anchor points is and how it works.
relativeToThe frame to which the point is being anchored. This
attribute is optional; if omitted, the default is the frame’s parent.
relativePointThe point to attach to on the relativeTo frame. This
attribute is optional; if omitted, the default is the point being anchored.
In addition to these attributes, the <Anchor> element can contain an
<Offset> element, with which you can specify an offset in absolute or relative
dimensions (this element is used in the same way as the <Size> element,
allowing xand yattributes, or an absolute or relative dimension definition).
The code for BagBuddy anchors the center point of the new frame to the center
of UIParent, which spans the full game screen.
Along the same lines, the following example creates a new frame called
MyFrame1 and another frame called MyFrame2. The first frame sits in the
center of the user interface, and the second frame sits directly to the right of
MyFrame1. This is accomplished by anchoring the top-left point of MyFrame2 to
148 Part II Programming in World of Warcraft
the top-right point of MyFrame1. In this way the top edges are aligned with
each other, and the frames sit side by side.
<Frame name=“MyFrame1“ parent=“UIParent“>
<Size x=“50“ y=“50“/>
<Anchor>
<Anchor point=“CENTER“ relativePoint=“CENTER“/>
</Anchors>
</Frame>
<Frame name=“MyFrame2“ parent=“UIParent“>
<Size x=“50“ y=“50“/>
<Anchor>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ i
relativeTo=“MyFrame“/>
</Anchors>
</Frame>
In this example, the top-left corner of MyFrame2 is attached to the top-right
corner of MyFrame1, aligning their top edges and placing them side-by-side.
When there is no offset, the <Offset> tag can be left out entirely, and the
<Anchor> tag can be made self-closing. The frames could be aligned using
the left point of MyFrame2 and the right point of MyFrame1, but if the frames are
different sizes, the top edges would not align.
Sticky Anchors
Anchoring a frame is not a one-time placement used to position the frame, but
rather a sticky attachment between two objects. In the preceding example, if
you later move Frame1,Frame2 will follow it to obey the defined anchor points.
SetAllPoints
If you want an object to have the same placement and size as another frame,
you can use the setAllPoints XML attribute, or the SetAllPoints() method.
This sets all of the anchor points on the second frame to the same points on the
parent frame. You’ll see this attribute in use later in this chapter.
Anchor Examples
The easiest way to visualize anchoring is to look at examples and determine
how the objects might be anchored together. Table 9-1 contains a number of
anchor examples, along with the anchor points that were used. Each of these
examples attaches FrameA to FrameB.
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 149
Table 9-1: Anchoring Examples
DESCRIPTION EXAMPLE
FrameB’s TOPLEFT anchored to FrameA’s TOPRIGHT
FrameB’s TOPLEFT anchored to FrameA’s RIGHT
FrameB’s TOPLEFT anchored to FrameA’s BOTTOMRIGHT
FrameB’s TOP anchored to FrameA’s BOTTOM
FrameB’s RIGHT anchored to FrameA’s LEFT with an x-offset
of 5 and a y-offset of 5
Using Lua to Create Frames
<Frame name=“BagBuddy“ parent=“UIParent“>
<Size x=“384“ y=“512“/>
<Anchors>
<Anchor point=“CENTER“ relativePoint=“CENTER“ i
relativeTo=“UIParent“/>
</Anchors>
</Frame>
The equivalent definition in Lua looks like the following:
CreateFrame(“Frame“, “BagBuddy“, UIParent)
BagBuddy:SetWidth(384)
BagBuddy:SetHeight(512)
BagBuddy:SetPoint(“CENTER“, UIParent, “CENTER“)
The CreateFrame function takes several arguments. The first argument is a
string that tells WoW what type of frame to create. This is the same string as
the XML tag you are using (in this case Frame). If you were creating a status
bar instead of a frame, you would specify StatusBar. The second argument
is the name of the frame (this is optional, because you can create frames that
have no names). The third argument is the parent frame object, not the name
of the parent.
150 Part II Programming in World of Warcraft
You can find more information on the frame methods used in this code in
the Widget reference.
Adding Layers of Textures and Font Strings
If you tried to re-create any of the prior frame definitions (or loaded the
BagBuddy addon), you might have been confused as to why you couldn’t see
any of the frames. Although the frames were created and placed on screen,
they did not have any visual components for you to see. This section introduces
textures and font strings:
TextureA texture is used to display some sort of graphic, color, or
color gradient within the game. Textures are created using the <Texture>
XML element.
FontStringA font string is used to display text in a specific font, size,
and color. Font strings can be further customized to display outlines,
drop shadows, and other standard effects. Font strings are created using
the <FontString> XML element.
Layering Frames and Graphics
To understand how to layer graphics and frames to display correctly, you
must first know a bit about the different layering techniques and how the user
interface is rendered.
Frame Strata
The most basic level of frame layering is the frame strata. Simply, all the frames
in a given frame strata are rendered later than frames in a lower strata, and
before those in a higher strata. Overlapping frames will be displayed layered
from lowest to highest. Table 9-2 describes the available frame strata.
Table 9-2: Possible Frame Strata Values from Lowest to Highest
FRAME STRATA DESCRIPTION
BACKGROUND For frames that don’t interact with the mouse. Any frame
in this strata is blocked from receiving mouse events
unless the frame level is higher than 1.
LOW Used by the default user interface for the buff frame,
durability frame, party interface, and pet frame.
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 151
FRAME STRATA DESCRIPTION
MEDIUM Default frame level for UIParent, and all children of
UIParent, unless overwritten.
HIGH Used by the default user interface for the action buttons
and tutorial frames, as well as the interface error and
warning frames.
DIALOG Used for any dialog-type frame that pops up and expects
user interaction.
FULLSCREEN Any full-screen frame such as the World Map or the User
Interface options should reside in this frame strata.
FULLSCREEN_DIALOG A dialog strata that exists above the FULLSCREEN strata,
for dialogs and dropdown menus.
TOOLTIP Highest frame strata available. Used for mouseover
tooltips so they are displayed regardless of the strata.
PARENT Inherit the frame strata of the parent frame.
Setting a frame to be drawn on a specific strata is easy; you simply include
the frameStrata attribute in the XML definition or use the SetFrameStrata()
method. For example:
<Frame name=“MyFrame“ frameStrata=“HIGH“>
</Frame>
or
MyFrame:SetFrameStrata(“HIGH“)
This is the technique used by the default user interface to allow pop-up
windows such as the confirmation dialog to appear over any other frames that
might be displayed on screen.
Frame Levels
Within a frame strata, each frame has a frame level, which determines the
order in which it is rendered (from lowest to highest). Frame levels can be
messy to set, but sometimes they are the only way to accomplish a specific
type of layering. When FrameA contains a child, FrameB, the frame level of
FrameB will automatically be one higher than that of FrameA. This means that
any child frames will (by default) be rendered on top of their parent, if they
are overlapping elements. The frame level can be set using the frameLevel
attribute, which should be a number, or using the SetFrameLevel() method.
152 Part II Programming in World of Warcraft
In addition, a frame can be marked as a top-level frame using the toplevel
attribute or the SetTopLevel() method. A top-level frame is automatically
promoted to the highest frame level on a given strata when it is clicked, so it
is shown on top. This is useful when frames are movable to bring the frame
that is being moved to the front. The following is an example frame with
frameStrata,frameLevel,andtoplevel all set:
<Frame name=“MyFrame“ frameStrata=“HIGH“ frameLevel=“5“ toplevel=“true“>
</Frame>
or in Lua:
MyFrame = CreateFrame(“Frame“, “MyFrame“)
MyFrame:SetFrameStrata(“HIGH“)
MyFrame:SetFrameLevel(5)
MyFrame:SetToplevel(true)
Graphical Layers
All textures and font strings within a frame are grouped into graphical layers.
When creating a new texture or font string you must specify on which layer
the graphics should be drawn. The various layer levels are listed in Table 9-3
in order from the backmost layer, to the frontmost layer.
Table 9-3: Graphical Layers
LAYER DESCRIPTION
BACKGROUND The background of your frame should be placed here.
BORDER Holds any graphical borders or artwork that need to appear above
the BACKGROUND layer but below any other layer.
ARTWORK For your frame’s artwork. This is typically any nonfunctional
decorative or separating artwork that needs to appear above the
background and border but below the functional portions of the
frame.
OVERLAY The highest standard layer; any elements that need to appear above
all other layers should be placed here.
HIGHLIGHT This special layer is displayed only when the mouse is moved over
the frame that is parent to the textures and font strings on the layer.
For this layer to function properly, the frame must have mouse
events enabled.
Figure 9-2 shows the first four layers using colored textures and different
font strings. These images are then placed on top of each other and layered by
the user interface.
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 153
Figure 9-2: Graphics layers rendered in-game
Figure 9-3 shows the highlight layer being displayed by moving the mouse
over the containing frame.
Figure 9-3: Highlight layer being shown on mouseover
For graphical elements that exist within the same draw layer of the same
frame, the rendering order is random. Font strings are always rendered on
top of textures within the same graphical layer, to ensure the text is displayed
over the graphic. As a result, there is no need to put your text on a separate
higher graphical layer to be visible.
BagBuddy Frame Design
Now that you have all the terminology straight, you can start building the
BagBuddy frame. Normally when creating a new addon, I hand sketch what
I would like the frame to look like, and how I would like it to operate.
This gives me something to work from when writing my code. Rather than
subjecting you to my horrible drawing skills, you can see the finished addon
in Figure 9-4.
You may notice that the frame looks a little bit like the bank frame. That’s
because the artwork is actually old artwork for the bank! The designers left
the graphics in the game files, so you’re able to use them. This allows you to
154 Part II Programming in World of Warcraft
create a frame that fits within the Blizzard style, while not requiring you to be
agraphicartist.
Figure 9-4: BagBuddy frame
In the top-left corner there is a circular graphic showing gears. This is an
item icon, shaped to fit the circle in the correct way. In the top-right corner
you can see a close button. When the user clicks this button, the frame closes.
At the top of the frame, a text string is displayed, telling the user the name of
the addon.
In the middle of the frame you can see a list of items. Moving your mouse
over the items displays the tooltip, as you might expect. Where the bank bags
might normally be are a series of colored orbs. These orbs allow you to filter
the item list by item quality (note that the colors match the item rarity colors
in-game).
At the bottom of the frame is a line of status text that shows how many items
were found. Next to that are two buttons that allow you to page through the
results. The button on the left moves you to the previous page, and the button
on the right moves you to the next page. Finally, there is a small edit box at the
very bottom of the frame that allows you to search for items by name. In this
case we’ve set the filter to the letter ‘‘g’’ and have found 14 results that contain
that letter.
Over the course of this chapter, you create the frame background, portrait
icon, title text, and status text.
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 155
Finding Graphics
You may be wondering how you might browse through the game files, looking
for a graphic to add to your frames. In Chapter 7 you were shown how to
extract the interface art, but the files that are extracted cannot be natively
viewed on most computers.
Luckily, you have two easy ways to browse those pictures. The first is an
addon that you can run in the game, and the second is a website that makes it
easy to browse the images.
TexBrowser AddOn
The author of Omen2 and other popular addons, Antiarc, has written an
in-game browser for the textures included in the game files. The addon is
called TexBrowser and you can find it at http://wow.curse.com/downloads/
wow-addons/details/texbrowser.aspx.
Because this addon contains a large list of the available textures, it does not
load automatically (this helps prevent slowing down your login and normal
gameplay). You can use AddonLoader (discussed in Chapter 8) or run the
commands listed on the addon’s webpage:
/run LoadAddOn(“TexBrowser“)
/tex
Figure 9-5 shows the TexBrowser window, viewing different available tex-
tures. One neat feature of TexBrowser is that it’s not limited to the interface
textures, but actually lists some textures that are used in the game environment,
such as spell textures.
ArtBrowser on Wowprogramming.com
To allow you to view the available graphics without having access to World
of Warcraft, we created a web application that allows you to browse the
textures. Just load http://wowprogramming.com/utils/artbrowser in your
web browser, and you’ll have access to all of the interface images in easy-to-
view PNG format.
Adding Textures
Textures are two-dimensional graphics that are rendered by the game client
for the user interface. A texture can consist of a graphics file loaded from disk,
a solid color, or a gradient from one color to another. The following is a very
basic texture definition:
<Layers>
<Layer level=“BACKGROUND“>
156 Part II Programming in World of Warcraft
<Texture name=“$parent_Icon“ i
file=“Interface\Icons\Ability_Rogue_Sprint“>
<Size x=“50“ y=“50“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
</Texture>
</Layer>
</Layers>
Figure 9-5: TexBrowser viewing the available textures
Remember that all texture definitions must happen inside a frame definition,
so first you indicate that you’re going to define the details of the graphical
layers. Next you create a layer on the correct level, and inside you define the
new texture.
A texture definition is very similar to the frame definitions you have already
seen. Textures are both sized and anchored the same way as frames. A new
attribute, file, is introduced here, used to specify a texture file to be loaded
and displayed. If you were to include this definition in your BagBuddy addon
you would see an icon in the very center of your screen.
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 157
Defining BagBuddy’s Background Textures
Open BagBuddy.xml and add the following code after the </Anchors> tag:
<Layers>
<Layer level=“BORDER“>
<Texture file=“Interface\BankFrame\UI-BankFrame-TopLeft“>
<Anchors>
<Anchor point=“TOPLEFT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-TopRight“>
<Anchors>
<Anchor point=“TOPRIGHT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-BotLeft“>
<Anchors>
<Anchor point=“BOTTOMLEFT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-BotRight“>
<Anchors>
<Anchor point=“BOTTOMRIGHT“/>
</Anchors>
</Texture>
</Layer>
</Layers>
For now, ignore the fact that you’re putting the background on the BORDER
layer. This code simply creates four new textures, one anchored to each corner
of the frame. Figure 9-6 shows the four different textures. These graphics,
when put together, create the frame shown in Figure 9-7.
Figure 9-6: From left to right: top left corner, top right corner, bottom left corner, and
bottom right corner textures.
158 Part II Programming in World of Warcraft
Figure 9-7: BagBuddy frame with BORDER textures
Coloring Textures
Most textures used in addons for World of Warcraft are made up of graphic
images that are placed on screen. However, the user interface also supports
the use of color to enhance a texture, display a solid color, or create a gradient
from one color to another.
Using Solid Colors
If you want to color a graphic image included with the file attribute, or just
display a solid color, you include the <Color> element in the texture definition.
This element accepts four attributes (r,g,b,a) as the three color components
red, green, and blue, and the alpha (opacity) value. Each should be a number
between 0.0 and 1.0. The following example shows a sample frame definition
that creates a red square in the center of the screen with 50% transparency:
<Frame name=“RedSquareTest“ parent=“UIParent“>
<Size x=“50“ y=“50“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Layers>
<Layer level=“BACKGROUND“ setAllPoints=“true“>
<Color r=“1.0“ g=“0.0“ b=“0.0“ a=“0.5“/>
</Layer>
</Layers>
</Frame>
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 159
Creating a Gradient
In addition to solid colors, a texture can also display a gradient between two
different colors. To do this, you define a minimum color and a maximum color,
using the <Gradient> tag. Figure 9-8 shows two example gradients.
Figure 9-8: Horizontal gradient (top) and vertical gradient (bottom)
The <Gradient> element takes a single, optional attribute, orientation,
which can be either HORIZONTAL or VERTICAL. The default is a horizontal
gradient. The tag must contain two elements, <MinColor> and <MaxColor>,
each of which takes the standard color attributes r,g,b,anda.
A<Gradient> tag alone won’t create a gradient; it must be combined with
a<Color> tag. At each step in the gradient, the color values from the <Color>
tag are multiplied by the current gradient value to determine what color is
displayed on screen. The easiest way to handle this is to create a white color
and then apply the gradient:
<Color r=“1.0“ g=“1.0“ b=“1.0“ a=“1.0“/>
This ensures that your gradient begins at your <MinColor> and ends at your
<MaxColor> because the base color value for each component is 1.0, which
doesn’t change the value it’s multiplied against. Here’s the XML used to create
the gradients shown in Figure 9-8:
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Frame name=“GradientTest“ parent=“UIParent“>
<Size x=“200“ y=“200“/>
<Anchors>
<Anchor point=“CENTER“ relativePoint=“CENTER“ i
relativeTo=“UIParent“/>
</Anchors>
<Layers>
<Layer level=“BACKGROUND“>
160 Part II Programming in World of Warcraft
<Texture name=“$parentHorizontal“>
<Size x=“200“ y=“100“/>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPLEFT“/>
</Anchors>
<Color r=“1.0“ g=“0.0“ b=“0.0“ a=“1.0“/>
<Gradient orientation=“HORIZONTAL“>
<MinColor r=“1.0“ g=“0.0“ b=“0.0“ a=“1.0“/>
<MaxColor r=“0.0“ g=“0.0“ b=“0.0“ a=“1.0“/>
</Gradient>
</Texture>
<Texture name=“$parentVertical“>
<Size x=“200“ y=“100“/>
<Anchors>
<Anchor point=“BOTTOMLEFT“ relativePoint=“BOTTOMLEFT“/>
</Anchors>
<Color r=“1.0“ g=“1.0“ b=“1.0“ a=“1.0“/>
<Gradient orientation=“VERTICAL“>
<MinColor r=“0.0“ g=“0.0“ b=“0.0“ a=“1.0“/>
<MaxColor r=“1.0“ g=“1.0“ b=“0.0“ a=“1.0“/>
</Gradient>
</Texture>
</Layer>
</Layers>
</Frame>
</Ui>
Adding the Portrait Texture
The reason the previous section placed the seemingly background textures on
the BORDER layer was to make the portrait graphic that will appear in the circle
at the top-left fit correctly. Trying to match the artwork perfectly would be
very difficult, so instead an image is created that is just slightly larger than the
opening, and layered so the excess is covered. This layering makes the images
appear to go together better than we could have achieved by editing them.
Add this layer definition before the BORDER layer, but within the <Layers>
element:
<Layer level=“BACKGROUND“>
<Texture name=“$parent_Portrait“ parentKey=“portrait“ i
file=“Interface\Icons\INV_Misc_EngGizmos_30“>
<Size x=“60“ y=“60“/>
<Anchors>
<Anchor point=“TOPLEFT“>
<Offset x=“7“ y=“-6“/>
</Anchor>
</Anchors>
</Texture>
</Layer>
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 161
The sizing and placement of this texture should be familiar to you by now,
but a new attribute called parentKey is included. To understand how it works,
you must know that a frame in Lua is just a special kind of Lua table. When
this attribute is set, WoW sets the named key in the parent frame’s table to be
the texture. In this case, you will be able to access the portrait texture in the
following ways:
BagBuddy_Portrait
BagBuddy.portrait
BagBuddy[“portrait“]
The first is possible because the texture is named using the name attribute.
The second uses the table access shortcut notation to access the portrait
key in the BagBuddy table. The third example just uses the full notation for
the same.
You can access the portrait using the first option because it has a distinct
name. The second two are a result of setting the parentKey attribute. This may
not seem useful right now, but it becomes incredibly helpful when working
with lots of subframes and textures.
Unfortunately, the graphic we are using is a square (shown in Figure 9-9)
and Figure 9-10 shows how everything appears when it is used. The major
problem is that the edges of the image stick out from behind the background
of the frame.
Figure 9-9: Texture being used for BagBuddy portrait circle
Thankfully, because this same problem crops up in a number of places in the
default user interface (such as the bag frames), Blizzard provides you with a
function that crops the image to appear as a circle, so it works correctly with
these types of frames. The function is called SetPortraitToTexture and it
takes the texture object as the first argument, followed by the filename to use.
To call this function, set an OnLoad script for this frame. You learn more
about frame scripts in Chapter 12, but essentially you are telling WoW to run
a specific script when this frame is being loaded. Add the following XML after
the </Layers> tag, and before the </Frame> tag:
<Scripts>
<OnLoad function=“BagBuddy_OnLoad“/>
</Scripts>
162 Part II Programming in World of Warcraft
Figure 9-10: BagBuddy with a square portrait image
Now you need to define the corresponding function in BagBuddy.lua:
function BagBuddy_OnLoad(self)
SetPortraitToTexture(self.portrait, i
“Interface\\Icons\\INV_Misc_EngGizmos_30“)
end
An OnLoad script is always passed a single argument, the frame itself. Just
call SetPortraitToTexture, passing in the portrait texture and the name of the
texture file to be displayed. Figure 9-11 shows the new version of the frame,
without the edges sticking out at the corner.
Creating Textures in Lua
In addition to creating frames, you can also create textures using Lua. Take
the definition of the portrait texture for BagBuddy:
<Layer level=“BACKGROUND“>
<Texture name=“$parent_Portrait“ parentKey=“portrait“>
<Size x=“60“ y=“60“/>
<Anchors>
<Anchor point=“TOPLEFT“>
<Offset x=“7“ y=“-6“/>
</Anchor>
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 163
</Anchors>
</Texture>
</Layer>
Figure 9-11: BagBuddy after using SetPortraitToTexture to crop the image
Assuming that you’ve already created the BagBuddy frame using Lua
previously, you could create this texture like this:
BagBuddy.portrait = BagBuddy:CreateTexture(“BagBuddy_Portrait“, i
“BACKGROUND“)
BagBuddy.portrait:SetWidth(60)
BagBuddy.portrait:SetHeight(60)
BagBuddy:SetPoint(“TOPLEFT“, 7, -6)
Because each texture and font string need to belong to a parent, there is
simply a method you call on the frame itself to create a new texture. The first
argument to CreateTexture is the name of the new texture and the second is
the layer on which to place the texture. There is a third argument that you
learn more about in Chapter 10.
If you then wanted to set a graphics file to be loaded, you could accomplish
this with the SetTexture method:
BagBuddy.portrait:SetTexture(“Interface\\Icons\\INV_Misc_EngGizmos_30“)
Indeed, you can specify a solid color using the same method; for example,
the following code sets the texture to be solid blue with 50% transparency:
BagBuddy.portrait:SetTexture(0.0, 0.0, 1.0, 0.5)
164 Part II Programming in World of Warcraft
Similarly, methods exist that allow you to set the gradient min and max
colors. In general, if there is a way to accomplish something in XML, there is a
way to accomplish it in Lua as well.
Creating Text using FontStrings
Adding text to your frames is very similar to adding textures. Inside a <Layer>
element, you define a <FontString> element and then customize it. Font
strings have many different XML attributes that can be used to change the
style of the displayed text, shown in Table 9-4.
Table 9-4: Attributes Available to FontString Elements
ATTRIBUTE DESCRIPTION
font The path to a font file to be used when displaying the text. This
can be a file included with WoW, or a true type font supplied by
a custom addon.
bytes A positive number expressing a limit on the number of
characters to be displayed in the FontString.
text The text to be displayed.
spacing Sets the spacing, in pixels, between lines if the FontString has
multiple lines.
outline Specifies the outline type of the FontString. Should be one of
the following values: NONE,NORMAL,THICK.
monochrome A Boolean value specifying whether the font should be
monochromatic (grayscale).
nonspacewrap A Boolean value that specifies whether long strings without
spaces are wrapped or truncated. When this is true, the string is
wrapped.
justifyV Specifies the vertical justification of the text using one of the
following values: TOP,MIDDLE,BOTTOM.
justifyH Specifies the horizontal justification of the text as one of the
following values: LEFT,CENTER,RIGHT.
maxLines Specifies the maximum number of lines to be displayed in a
FontString.
indented Specifies whether or not lines after the first line in the
FontString are indented, if the FontString has multiple
lines.
inherits Specifies a font definition from which attributes and elements
should be inherited.
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 165
Further Customization
In addition to the XML attributes, the following elements can be added to a
FontString to customize the display:
<FontHeight>Can be specified using the val attribute, or using
<AbsValue> or <RelValue>. Specifies the height of the font string in pixels
or a relative value.
<Color>Changes the color of the font string; specified using the r,g,b,
and aattributes.
<Shadow>Adds a drop shadow to the font. The color and placement of
the shadow is specified by the <Color> and <Offset> elements, which are
required.
Using Font Definitions
Although having the flexibility to specify so many different attributes for each
font string is a good thing, it can become quite cumbersome when writing
addons and actually creating them regularly. You can delineate font (or font
string) definitions that can be used to inherit settings. Fonts and font strings
are a bit of an exception to the template system, which is covered in Chapter 10.
For now, use the predefined template GameFontNormal for the title string in the
BagBuddy window by adding the following code to the BagBuddy definition
in the <Layers> element, after the definition of the BACKGROUND layer:
<Layer level=“OVERLAY“>
<FontString name=“$parent_Title“ parentKey=“title“ inherits= i
“GameFontNormal“ text=“BagBuggy“>
<Anchors>
<Anchor point=“TOP“>
<Offset x=“0“ y=“-18“/>
</Anchor>
</Anchors>
</FontString>
</Layer>
Here you create a new font string on the OVERLAY layer, anchored to the top
of the frame. You place the text on the OVERLAY layer to ensure that it is always
displayed on top of the textures you have already defined, which exist in the
BACKGROUND and BORDER layer. You inherit the settings from the GameFontNormal
definition, which defines the gold-colored text that you see through the user
interface. Font definitions and templates are shown in Chapter 10, along with
further explanation about how to create your own templates.
166 Part II Programming in World of Warcraft
Creating FontStrings in Lua
The CreateFontString() methodcanbeusedtocreatenewfontstrings.It
takes three arguments, the name of the new font string, the layer on which to
draw the font string, and an optional font definition or template from which
to inherit. You could create the font string from the previous section with the
following code:
BagBuddy.title =
BagBuddy:CreateFontString(“BagBuddy_Title“, “OVERLAY“, i
“GameFontNormal“)
BagBuddy.title:SetPoint(“TOP“, 0, -18)
BagBuddy.title:SetText(“BagBuddy“)
Understanding Object Visibility
A somewhat confusing topic when dealing with UI objects is the concept
of visibility. For an object to be actually drawn on screen, it must fulfill the
following requirements:
1. The object must have some visual component, such as text, graphics,
background color, or border. A frame with none of these is not visible,
and a texture or font string without any contents is equally invisible.
2. The object must have a positive height and width. Although this may
seem obvious, it’s easy to forget one or the other.
3. The object must be placed somewhere within the bounds of the screen. If
it’s anchored outside the viewable window, it can’t be displayed.
4. The object and each of its parents must be shown.
In this case, the word ‘‘shown’’ means that the object is not hidden. An
object can be hidden in two ways:
It can start out hidden by setting the hidden attribute in the XML definition
to true.
It can be made hidden by calling the object’s :Hide() method.
There are two API functions that can be used to troubleshoot an object’s
visibility:
IsShown()—Returns 1if the frame is shown, a state that can be toggled
using the Show() and Hide() methods.
IsVisible()—Returns 1if the frame and all of its parents are shown.
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 167
Finding Existing Frames
Frequently when placing your own frames on the screen, you will want to
anchor them to an existing frame. If you know the name of the frame you
can easily accomplish this, but as you’ve seen, sometimes the frame structure
is a bit convoluted. In the World of Warcraft 3.2 patch, a new utility was
added that allows you to see informationabouttheframesatagivenpointon
the screen. You can invoke this utility with the /framestack slash command,
which is used to toggle it on and off. Figure 9-12 shows how the information
is displayed in-game.
Figure 9-12: /framestack tooltip showing the frames under the mouse cursor
The tooltip provides quite a bit of information. It lists the frames within a
given frame strata from highest to lowest. Within each strata, it lists the frame
along with the frame level in that strata (again from highest to lowest). That
enables you to see the way in which the current location on the screen is being
rendered, and also makes it easier to see how frames that you didn’t create
might be constructed.
Summary
This chapter introduced the basics of creating frames in both XML and Lua.
You learned about the sizing mechanisms, and the anchoring system that is
used to position frames on the screen. In addition you developed the base
look for the BagBuddy addon using layers to ensure the graphics appear
correctly.
Chapter 10 shows how you can use frame templates to ease the burden of
creating lots of very similar frames.
168 Part II Programming in World of Warcraft
The Code
BagBuddy.toc
## Interface: 30200
## Title: BagBuddy
## Notes: A handy helper that allows you to filter your inventory
BagBuddy.lua
BagBuddy.xml
BagBuddy.lua
function BagBuddy_OnLoad(self)
SetPortraitToTexture(self.portrait, i
“Interface\\Icons\\INV_Misc_EngGizmos_30“)
end
BagBuddy.xml
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Frame name=“BagBuddy“ parent=“UIParent“>
<Size x=“384“ y=“512“/>
<Anchors>
<Anchor point=“CENTER“ relativePoint=“CENTER“ i
relativeTo=“UIParent“/>
</Anchors>
<Layers>
<Layer level=“BACKGROUND“>
<Texture name=“$parent_Portrait“ parentKey=“portrait“ i
file=“Interface\Icons\INV_Misc_EngGizmos_30“>
<Size x=“60“ y=“60“/>
<Anchors>
<Anchor point=“TOPLEFT“>
<Offset x=“7“ y=“-6“/>
</Anchor>
</Anchors>
</Texture>
</Layer>
<Layer level=“BORDER“>
<Texture file=“Interface\BankFrame\UI-BankFrame-TopLeft“>
<Anchors>
<Anchor point=“TOPLEFT“/>
</Anchors>
</Texture>
Chapter 9 Working with Frames, Widgets, and Other Graphical Elements 169
<Texture file=“Interface\BankFrame\UI-BankFrame-TopRight“>
<Anchors>
<Anchor point=“TOPRIGHT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-BotLeft“>
<Anchors>
<Anchor point=“BOTTOMLEFT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-BotRight“>
<Anchors>
<Anchor point=“BOTTOMRIGHT“/>
</Anchors>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnLoad function=“BagBuddy_OnLoad“/>
</Scripts>
</Frame>
</Ui>
CHAPTER
10
Saving Time with Frame
Templates
Chapter 9 introduced the concept of using frame templates to save time. Rather
than specifying the same attributes and elements over and over again, you can
create a single template and later inherit from it when creating new frames. In
this chapter you’ll create a frame template for the item slots in BagBuddy and
then create frames dynamically from the template.
Understanding Templates
Templates provide developers with an easy way to define common sets
of attributes and elements and then create multiple frames that utilize the
template, inheriting all of that setup. Say, for example, that you need to create
a row of three 16×16 buttons that contain a single texture. Without templates,
the code might look something like this:
<Button name=“Button1“>
<Size x=“16“ y=“16“/>
<Layers>
<Layer level=“BACKGROUND“>
<Texture name=“$parentIcon“ parentKey=“icon“>
<Color r=“1.0“ g=“1.0“ b=“1.0“/>
</Texture>
</Layer>
</Layers>
</Button>
<Button name=“Button2“>
<Size x=“16“ y=“16“/>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ relativeTo=“Button2“/>
171
172 Part II Programming in World of Warcraft
</Anchors>
<Layers>
<Layer level=“BACKGROUND“>
<Texture name=“$parentIcon“ parentKey=“icon“>
<Color r=“1.0“ g=“1.0“ b=“1.0“/>
</Texture>
</Layer>
</Layers>
</Button>
<Button name=“Button3“>
<Size x=“16“ y=“16“/>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ relativeTo=“Button2“/>
</Anchors>
<Layers>
<Layer level=“BACKGROUND“>
<Texture name=“$parentIcon“ parentKey=“icon“>
<Color r=“1.0“ g=“1.0“ b=“1.0“/>
</Texture>
</Layer>
</Layers>
</Button>
Using frame templates, you could instead write the following:
<Button name=“MyButtonTemplate“ virtual=“true“>
<Size x=“16“ y=“16“/>
<Layers>
<Layer level=“BACKGROUND“>
<Texture name=“$parentIcon“ parentKey=“icon“>
<Color r=“1.0“ g=“1.0“ b=“1.0“/>
</Texture>
</Layer>
</Layers>
</Button>
<Button name=“Button1“ inherits=“MyButtonTemplate“/>
<Button name=“Button2“ inherits=“MyButtonTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ relativeTo=“Button2“/>
</Anchors>
</Button>
<Button name=“Button3“ inherits=“MyButtonTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ relativeTo=“Button2“/>
</Anchors>
</Button>
</Ui>
Using a template in this case only saves 13 lines, but imagine if you needed to
create a row of eight buttons instead of three! You can use the CreateFrame()
function to create new frames, saving yourself quite a bit of code.
Chapter 10 Saving Time with Frame Templates 173
Templates can be created and inherited for the following type of elements:
Frames
Font strings
Textures
Animations
Animation groups
In addition, the template system is overloaded to work with font definitions
and font strings. A font string can, of course, inherit from a font string
template and inherit the attributes and elements, but may also inherit from a
font definition. When this happens, the font string does not really inherit the
attributes, but rather links itself to the font definition. If the font definition
were to later change, the font string would change along with it.
Throughout this chapter, font definitions are referred to as a distinct concept
from templates.
Advantages of Using Templates
The primary advantage of using templates is the capability to create complex
elements repeatedly without needing to retype them for each instance. To
accomplish this, templates take advantage of the means to automatically
name elements using $parent, and make sub-elements accessible using the
parentKey attribute.
Naming Elements Using $parent
Using the string $parent in an element’s name in order to include the parent’s
name becomes very important when working with templates, to ensure that
frames are consistently named. Prior to the 3.0 patch, this was the primary
method used to name frames in the default user interface.
Many of the default templates, such as the dropdown menu template,
require a frame to have a name for them to function properly. They make
heavy use of parent-named textures and sub-frames in the code that manages
them. In the future, these templates might be converted to use the parentKey
attribute instead, so the naming required might be removed, but there have
been no moves in that direction yet.
In the preceding example, the textures created in the template will be
accessible as Button1Icon,Button2Icon,andButton3Icon. Programmatically,
code might find the icon of such a button using the following code (assuming
that the variable self is set to one of the three buttons):
_G[self:GetName() .. “Icon“]:SetTexture(1, 0, 0)
This code fetches the name of the frame, concatenates the string Icon on
the end, and looks that key up in the global environment. It then calls the
174 Part II Programming in World of Warcraft
SetTexture of the resulting texture, to color it red. Although accesses such as
this are better handled using the parentKey attribute, naming frames is still
very important. As shown at the end of Chapter 9, users and developers can
use the /framestack command to determine what frames are on screen at a
given point in time. If you make lots of unnamed frames, it is very difficult to
distinguish among them. For that reason, you are encouraged to create named
frames in addition to utilizing the parentKey attribute where appropriate.
Setting Keys Using the parentKey Attribute
In addition to being useful in normal frame definitions, the parentKey attribute
can be used in template definitions to make textures, font strings, and
sub-frames accessible. Rather than perform a name lookup, you could set
the texture of a button’s icon using the following code (assuming that the
variable self is set to one of the three buttons):
self.icon:SetTexture(1, 0, 0)
In addition to being more efficient, this method is easier to read and
doesn’t require the code to know whether or not frames are named. Although
the majority of the templates in the default user interface do not yet take
advantage of this feature, it’s a nice and easy way to define and access the
elements of a frame.
Creating a Template for BagBuddy’s Item Buttons
Each item slot in BagBuddy will show the item’s icon and the number of items
of a given type in your inventory. In addition, there will be a colored border
around each item showing its rarity (that is, purple for epic, blue for rare, and
so on). The default user interface already has a template that contains all of
these elements, called ItemButtonTemplate.
In fact, you could inherit directly from ItemButtonTemplate,butthat
wouldn’t be a very good example. In addition, if Blizzard makes any changes
to its template, your addon might break. Instead you will copy the code from
the FrameXML definition and adapt it to your own needs. Open BagBuddy.xml
and add the following at the top of the file, inside the <Ui> element:
<Button name=“BagBuddyItemTemplate“ virtual=“true“>
<Size>
<AbsDimension x=“37“ y=“37“/>
</Size>
<Layers>
<Layer level=“BORDER“>
<Texture name=“$parentIconTexture“ parentKey=“icon“/>
Chapter 10 Saving Time with Frame Templates 175
<FontString name=“$parentCount“ parentKey=“count“
inherits=“NumberFontNormal“ justifyH=“RIGHT“ hidden=“true“>
<Anchors>
<Anchor point=“BOTTOMRIGHT“>
<Offset>
<AbsDimension x=“-5“ y=“2“/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
<Layer level=“OVERLAY“>
<Texture name=“$parentGlow“ parentKey=“glow“ alphaMode=“ADD“
file=“Interface\Buttons\UI-ActionButton-Border“>
<Size x=“70“ y=“70“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Color r=“1.0“ g=“1.0“ b=“1.0“ a=“0.6“/>
</Texture>
</Layer>
</Layers>
</Button>
This template is named BagBuddyItemTemplate. Because the names of tem-
plates are global, you should ensure that your name won’t conflict with another
template. The easiest way to do this is to prefix it with some text and use a
meaningful name. You give the frame a size, and define a single graphics layer
on the BORDER level. Inside this group, you create an icon texture and a single
font string to display the item count.
Setting Button Textures
Each button in World of Warcraft can have a few different types of textures that
are displayed in different states. The NormalTexture is shown when the button
is in a resting state. When the user clicks the button, the PushedTexture is
displayed. Finally the HighlightTexture appears when the mouse is hovering
over the button. Define these in BagBuddyItemTemplate,afterthe</Layers>
tag but before the </Button> tag:
<NormalTexture name=“$parentNormalTexture“ file=“Interface\Buttons\UI- i
Quickslot2“>
<Size>
<AbsDimension x=“64“ y=“64“/>
</Size>
<Anchors>
<Anchor point=“CENTER“>
176 Part II Programming in World of Warcraft
<Offset>
<AbsDimension x=“0“ y=“-1“/>
</Offset>
</Anchor>
</Anchors>
</NormalTexture>
<PushedTexture file=“Interface\Buttons\UI-Quickslot-Depress“/>
<HighlightTexture file=“Interface\Buttons\ButtonHilight-Square“
alphaMode=“ADD“/>
The pushed and highlight textures inherit the size and the placement of the
normal texture, because the game just changes the image file being displayed.
You can see a new texture attribute that is used in the highlight texture, called
alphaMode. This attribute has five different options:
DISABLEIgnores the alpha channel completely when rendering the
texture.
BLENDUses the alpha channel with a normal blending overlay.
ALPHAKEYInterprets the alpha with any black value being transparent,
and any non-black value being opaque.
ADDUses the alpha channel with an additive blending overlay.
MODIgnores the alpha channel, multiplying the image against the back-
ground.
The template uses the ADD alpha mode to achieve its particular highlight
effect.
Creating New Frames with Your Template
Now that you’ve defined the template, you need to actually create some frames
using it. Although you could do this in XML, you would need to create 24
different frames and set anchors on each of them individually. Instead you
will do it using Lua, which is much shorter. Open BagBuddy.lua and add the
following inside the BagBuddy_OnLoad function:
-- Create the item slots
self.items = {}
for idx = 1, 24 do
local item = CreateFrame(“Button“, “BagBuddy_Item“ .. idx, self, i
“BagBuddyItemTemplate“)
self.items[idx] = item
if idx == 1 then
item:SetPoint(“TOPLEFT“, 40, -73)
elseif idx == 7 or idx == 13 or idx == 19 then
Chapter 10 Saving Time with Frame Templates 177
item:SetPoint(“TOPLEFT“, self.items[idx-6], “BOTTOMLEFT“, 0, -7)
else
item:SetPoint(“TOPLEFT“, self.items[idx-1], “TOPRIGHT“, 12, 0)
end
end
You first create a table that will be used to store the individual buttons.
This will make it easier to iterate over the buttons when displaying items. For
each index you create a new button from the template you created. Then you
programmatically set the anchors:
If you’re creating the first button, anchor it to the frame itself in the first
button slot.
When creating the first button in any subsequent row, anchor the new
button to the first column of the prior row.
For all other buttons, anchor the new button to the previous button on
the row.
By contrast, accomplishing the same thing in XML would require 3 to 5
lines for each button for a total of somewhere between 70 and 250 lines. When
creating just a few instances of a template, I tend to include them in the XML,
but whenever I’m doing something very repetitive like this I prefer to create
the frames in Lua.
As you move your mouse over the item buttons you can see the highlight
texture appear. This allows you to easily see which button you are currently
hovering over.
Exploring Font Definitions
Font definitions are a bit of an exception when it comes to the template system
in World of Warcraft. Although they use the same inheritance mechanism,
they work quite differently. This section looks at a specific font definition to
provide an understanding of how they work. You can find the definition of
GameFontNormalSmall in FontStyles.xml, which can be extracted using the
Blizzard Interface Toolkit, introduced in Chapter 8. The code for the template
is as follows:
<Font name=“GameFontNormalSmall“ inherits=“SystemFont_Shadow_Small“ i
virtual=“true“>
<Color r=“1.0“ g=“0.82“ b=“0“/>
</Font>
The font definition includes the virtual attribute, but it’s essentially ignored.
Remember, you are creating a font definition (which is an actual in-game object)
178 Part II Programming in World of Warcraft
rather than just creating a template. This particular definition inherits from
another template called SystemFont_Shadow_Small, defined in Fonts.xml:
<Font name=“SystemFont_Shadow_Small“ font=“Fonts\FRIZQT .TTF“
virtual=“true“>
<Shadow>
<Offset>
<AbsDimension x=“1“ y=“-1“/>
</Offset>
<Color r=“0“ g=“0“ b=“0“/>
</Shadow>
<FontHeight>
<AbsValue val=“10“/>
</FontHeight>
</Font>
This template doesn’t inherit from any other template, and actually defines
the font file that is used to display text, along with a drop shadow and the
height of the text. The font used is called Friz Quadrata and is included in
the game files. The font template defines a drop shadow to the bottom right
ofthetextwithanoffsetof1pixelineachdirection.Thecoloroftheshadow
is set to black, and the height of the font is set to 10 pixels.
When the GameFontNormalSmall font definition inherits from SystemFont
_Shadow_Small, it links itself to the original font. Any changes made to the
parent font will be reflected in the inheriting font. The only change the new
template makes is to set the color to gold, but any of the attributes or elements
defined in a font definition can be overridden while inheriting.
Altering a Font Definition
The major difference between templates and font definitions is that font
definitions can be altered once you are in-game, and the changes will trickle
down the inheritance tree. For example, you can run the following code to
change the height of SystemFont_Shadow_Small from 10 to 13:
/run SystemFont_Shadow_Small:SetFont(“Fonts\\FRIZQT .TTF“, 13)
Figure 10-1 shows the player unit frame and the social panel at the default
font size, and after running the code.
As you can see, only those elements that inherited from SystemFont_Shadow
_Small (and by inheritance GameFontNormalSmall) are changed. The color and
shadow definitions remain set, but the font size has been changed. In the same
way, you could actually replace the font file that is being used to display
some text, and it will immediately be reflected in-game throughout the font
inheritance tree.
Chapter 10 Saving Time with Frame Templates 179
Figure 10-1: The player unit frame and social panel with default (left) and altered (right)
font settings
Investigating UIPanelTemplates
There are a number of already defined templates that you may find
useful when creating your own addons. Many of them are defined in
UIPanelTemplates.xml, but there are templates defined throughout the
default user interface. This section explores a few of the more commonly used
templates with code to create an example and an image of each.
Run the following code to define a helper function that will enable you to
move any of the frames you have created (this function is used in the example
code):
function MakeMovable(frame)
frame:SetMovable(true)
frame:RegisterForDrag(“LeftButton“)
frame:SetScript(“OnDragStart“, frame.StartMoving)
frame:SetScript(“OnDragStop“, frame.StopMovingOrSizing)
end
180 Part II Programming in World of Warcraft
For now, just ignore what the code is doing; you will learn more about
interacting with widgets in Chapter 12.
UIPanelButtonTemplate
The UIPanelButtonTemplate template is used for the buttons on the main
game menu and on many of the panels in the user interface. The button can
be resized (in fact, you must supply a size because the template does not) and
contains a gold label in the center. Figure 10-2 shows the frame created by the
following code:
local frame = CreateFrame(“Button“, “UIPanelButtonTemplateTest“,
UIParent, “UIPanelButtonTemplate“)
frame:SetHeight(20)
frame:SetWidth(100)
frame:SetText(“Test Button“)
frame:ClearAllPoints()
frame:SetPoint(“CENTER“, 0, 0)
MakeMovable(frame)
Figure 10-2: Example frame created from UIPanelButtonTemplate
UIPanelCloseButton
The UIPanelCloseButton template (which lacks the word template in its name)
is used for the close button that appears on most of the panels in the user
interface. As a matter of fact, you should be careful if you click on the example
button you create, because it will hide your entire user interface due to a
script defined in the template. You can re-show your UI by pressing Alt+Z.
Figure 10-3 shows the close button created by the following code:
local frame = CreateFrame(“Button“, “UIPanelCloseButtonTest“,
UIParent, “UIPanelCloseButton“)
frame:ClearAllPoints()
frame:SetPoint(“CENTER“, 0, 0)
MakeMovable(frame)
Figure 10-3: Close button created using UIPanelCloseButton
Chapter 10 Saving Time with Frame Templates 181
UIPanelScrollBarTemplate
Although the UIPanelScrollBarTemplate template is meant to be used with
the built-in scroll frame templates, you could certainly instantiate it in other
circumstances. The template defines a button that scrolls up, a button that
scrolls down, and the scroll ‘‘knob’’ that can be dragged to set the scroll value.
Figure 10-4 shows the scroll bar created with the following code:
local frame = CreateFrame(“Slider“, “UIPanelScrollBarTemplateTest“, i
UIParent, “UIPanelScrollBarTemplate“)
frame:ClearAllPoints()
frame:SetPoint(“CENTER“, 0, 0)
frame:SetHeight(100)
frame:SetWidth(20)
frame:SetScript(“OnValueChanged“, nil)
frame:SetMinMaxValues(0, 100)
frame:SetValue(70)
MakeMovable(frame)
Figure 10-4: Scroll bar frame created using UIPanelScrollBarTemplate
InputBoxTemplate
When creating a new input box, you can use the InputBoxTemplate template
to create the background and border. It seems to have an issue when you create
it dynamically in Lua (in particular, the middle portion of the background
does not resize itself properly). Figure 10-5 shows the example created with
the following Lua code, designed to work around this bug:
local frame = CreateFrame(“EditBox“, “InputBoxTemplateTest“, i
UIParent, “InputBoxTemplate“)
frame:SetWidth(250)
frame:SetHeight(20)
InputBoxTemplateTestMiddle:ClearAllPoints()
182 Part II Programming in World of Warcraft
InputBoxTemplateTestMiddle:SetPoint(“LEFT“, InputBoxTemplateTestLeft, i
“RIGHT“, 0, 0)
InputBoxTemplateTestMiddle:SetPoint(“RIGHT“, InputBoxTemplateTestRight,i
“LEFT“, 0, 0)
frame:ClearAllPoints()
frame:SetPoint(“CENTER“, 0, 0)
frame:SetAutoFocus(false)
frame:SetText(“This is an example input box“)
MakeMovable(frame)
If you’d rather use XML you can create the frame in the following way to
avoid the bug (which is a result of the frame being created initially without a
size):
<EditBox name=“InputBoxTemplateTest“ parent=“UIParent“ inherits= i
“InputBoxTemplate“>
<Size x=“250“ y=“20“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Scripts>
<OnLoad>
self:SetAutoFocus(false)
</OnLoad>
</Scripts>
</EditBox>
Figure 10-5: Example input box using InputBoxTemplate
UICheckButtonTemplate
To create a toggleable checkbox, you can use UICheckButtonTemplate.This
template contains the actual check button itself, with a text label on its right
side. Figure 10-6 shows the example created with the following code:
local frame = CreateFrame(“CheckButton“, “UICheckButtonTemplateTest“, i
UIParent, “UICheckButtonTemplate“)
frame:ClearAllPoints()
frame:SetPoint(“CENTER“, 0, 0)
_G[frame:GetName() .. “Text“]:SetText(“Example checkbutton“)
MakeMovable(frame)
Figure 10-6: Example check button using UICheckButtonTemplate
Chapter 10 Saving Time with Frame Templates 183
TabButtonTemplate
The tabs at the bottom of the character and social panels are created using
TabButtonTemplate. To work with them properly, you can use a number
of utility functions defined in UIPanelTemplates.lua. One such function
is PanelTemplates_TabResize, which is used in the following example.
Figure 10-7 shows the tab button resulting from the code.
local frame = CreateFrame(“Button“, “TabButtonTemplateTest“, UIParent, i
“TabButtonTemplate“)
frame:ClearAllPoints()
frame:SetPoint(“CENTER“, 0, 0)
frame:SetText(“Example Tab“)
PanelTemplates_TabResize(frame)
MakeMovable(frame)
Figure 10-7: Panel tab created using TabButtonTemplate
UIRadioButtonTemplate
To create a radio button rather than a checkbox, you can create a frame using
UIRadioButtonTemplate. To deselect any other radio buttons when one is
selected, you would need to manage that logic on your own. Figure 10-8
shows the radio button created using the following example code:
local frame = CreateFrame(“CheckButton“, “UIRadioButtonTemplateTest“, i
UIParent, “UIRadioButtonTemplate“)
frame:SetHeight(20)
frame:SetWidth(20)
frame:ClearAllPoints()
frame:SetPoint(“CENTER“, 0, 0)
_G[frame:GetName() .. “Text“]:SetText(“Example radio button“)
MakeMovable(frame)
Figure 10-8: Radio button created using UIRadioButtonTemplate
Summary
This chapter showed how templates can be used to better organize frame,
texture, and font string definitions. You created a template for BagBuddy and
used it to dynamically create new item buttons in Lua. You also explored the
various UIPanelTemplates already defined in the default user interface.
184 Part II Programming in World of Warcraft
The Code
BagBuddy.lua
function BagBuddy_OnLoad(self)
SetPortraitToTexture(self.portrait, i
“Interface\\Icons\\INV_Misc_EngGizmos_30“)
-- Create the item slots
self.items = {}
for idx = 1, 24 do
local item = CreateFrame(“Button“, “BagBuddy_Item“ .. idx, i
self, “BagBuddyItemTemplate“)
self.items[idx] = item
if idx == 1 then
item:SetPoint(“TOPLEFT“, 40, -73)
elseif idx == 7 or idx == 13 or idx == 19 then
item:SetPoint(“TOPLEFT“, self.items[idx-6], “BOTTOMLEFT“, i
0, -7)
else
item:SetPoint(“TOPLEFT“, self.items[idx-1], “TOPRIGHT“, i
12, 0)
end
end
end
BagBuddy.xml
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Button name=“BagBuddyItemTemplate“ virtual=“true“>
<Size>
<AbsDimension x=“37“ y=“37“/>
</Size>
<Layers>
<Layer level=“BORDER“>
<Texture name=“$parentIconTexture“ parentKey=“icon“/>
<FontString name=“$parentCount“ parentKey=“count“ i
inherits=“NumberFontNormal“ justifyH=“RIGHT“ hidden=“true“>
<Anchors>
<Anchor point=“BOTTOMRIGHT“>
<Offset>
<AbsDimension x=“-5“ y=“2“/>
</Offset>
</Anchor>
</Anchors>
</FontString>
Chapter 10 Saving Time with Frame Templates 185
</Layer>
<Layer level=“OVERLAY“>
<Texture name=“$parentGlow“ parentKey=“glow“ i
alphaMode=“ADD“ file=“Interface\Buttons\UI-ActionButton-Border“>
<Size x=“70“ y=“70“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Color r=“1.0“ g=“1.0“ b=“1.0“ a=“0.6“/>
</Texture>
</Layer>
</Layers>
<NormalTexture name=“$parentNormalTexture“ i
file=“Interface\Buttons\UI-Quickslot2“>
<Size>
<AbsDimension x=“64“ y=“64“/>
</Size>
<Anchors>
<Anchor point=“CENTER“>
<Offset>
<AbsDimension x=“0“ y=“-1“/>
</Offset>
</Anchor>
</Anchors>
</NormalTexture>
<PushedTexture file=“Interface\Buttons\UI-Quickslot-Depress“/>
<HighlightTexture i
file=“Interface\Buttons\ButtonHilight-Square“ alphaMode=“ADD“/>
</Button>
<Frame name=“BagBuddy“ parent=“UIParent“>
<Size x=“384“ y=“512“/>
<Anchors>
<Anchor point=“CENTER“ relativePoint=“CENTER“ i
relativeTo=“UIParent“/>
</Anchors>
<Layers>
<Layer level=“BACKGROUND“>
<Texture name=“$parent_Portrait“ parentKey=“portrait“ i
file=“Interface\Icons\INV_Misc_EngGizmos_30“>
<Size x=“60“ y=“60“/>
<Anchors>
<Anchor point=“TOPLEFT“>
<Offset x=“7“ y=“-6“/>
</Anchor>
</Anchors>
</Texture>
</Layer>
<Layer level=“OVERLAY“>
<FontString name=“$parent_Title“ parentKey=“title“ i
186 Part II Programming in World of Warcraft
inherits=“GameFontNormal“ text=“BagBuggy“>
<Anchors>
<Anchor point=“TOP“>
<Offset x=“0“ y=“-18“/>
</Anchor>
</Anchors>
</FontString>
</Layer>
<Layer level=“BORDER“>
<Texture file=“Interface\BankFrame\UI-BankFrame-TopLeft“>
<Anchors>
<Anchor point=“TOPLEFT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-TopRight“>
<Anchors>
<Anchor point=“TOPRIGHT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-BotLeft“>
<Anchors>
<Anchor point=“BOTTOMLEFT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-BotRight“>
<Anchors>
<Anchor point=“BOTTOMRIGHT“/>
</Anchors>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnLoad function=“BagBuddy_OnLoad“/>
</Scripts>
</Frame>
</Ui>
CHAPTER
11
Exploring the World
of Warcraft API
World of Warcraft is an incredibly complex game. At any given momenteven
with the default UIthere can be a massive amount of information on the
screen: unit frames showing players’ and mobs’ health, mana, hostility, and
PvP status; buffs and their durations; action buttons with various states such
as cooldown, number of uses, and range indication; tracked quests; and so on.
To get much of this information, you must query the application programming
interface,orAPI.
NOTE API is a generic term in the software field describing a set of functions and
data structures that are used by a program to interact with its environment.
Another example of an API is Win32, which allows Windows programs to read and
create files, display controls such as buttons and checkboxes, communicate over a
network, launch other applications, and so on.
Similar to the API that the Lua programming language provides, World of
Warcraft provides a large set of functions that allow you to query information
about the state of the game. Other functions allow you to change something
about the client, such as selecting different quests in the quest log, or changing
what map is displayed in the world map frame. This chapter introduces you
to the API system provided by World of Warcraft.
Understanding the WoW API
The World of Warcraft API consists of several types of functions including
C functions (functions defined in C and exposed to the Lua environment),
Lua-defined functions (found in Blizzard’s FrameXML files), and protected
187
188 Part II Programming in World of Warcraft
functions, which can only be used by Blizzard code because of security and
automation concerns.
The functions cover quite a wide range of topics from changing game
settings to posting auctions. Some operate like Lua library functions; others
provide a specific interface to some aspect of gameplay.
As you progress through this chapter, you may want to flip to Chapter 27,
‘‘API Reference,’’ to see the details of the various APIs presented. It will both
help you to understand the content of this chapter and give you a glimpse into
the kinds of functions available to you.
Normal APIs
Most of the built-in functions you’ll use on a regular basis are defined in
C, rather than in Lua. They interact with the various subsystems of the
WoW client to gather information about the state of the game and to take
action in several ways. One example is UnitHealth, which returns the health
of a specified unit (a creature or player referenced by a unit ID). Run the
following statement in-game, and it displays your current number of hit
points:
/run print(UnitHealth(“player“))
The unit ID in this case is “player“, which always refers to you, the player.
Use “target“ instead, and it prints the health of your target, or nil if you have
no target.
This introduces a recurring theme in the WoW API. Many groups of func-
tions operate on a certain type of data. In the preceding example, the data
type is unit ID. Some of the many functions that use unit IDs are UnitMana,
UnitExists,andUnitLevel.
Library-like APIs
The Lua standard libraries provide a wide range of functions for string
manipulation, mathematic operations, and so on. However, not all functions
that are exposed in a standard Lua installation are appropriate for inclusion
in WoW. Because addons are not allowed to access any files directly, the
io library obviously isn’t included. The debug and os libraries also contain
some more potentially hazardous functions, so they aren’t included. However,
some of the functions provided by these libraries are benign enough that their
functionality has been exposed through new functions. Table 11-1 shows some
of these library-API relationships.
NOTE Some of the parameters and returns may vary between the standard
versions and those included in the WoW client. See Chapter 27, ‘‘API Reference,’’
for documentation of each function.
Chapter 11 Exploring the World of Warcraft API 189
Table 11-1: Library Functions and Their API Equivalents
STANDARD LIBRARY EQUIVALENT WOW API
os.date date
os.time time
os.difftime difftime
debug.traceback debugstack
In addition to direct library translations, several functions specific to WoW
play a support role in addon development but do not directly relate to anything
in-game. These have semantics similar to library functions but are technically
part of the WoW API. They are easily identifiable because their names are
entirely lowercasedebugprofilestart and hooksecurefunc,forinstance.
Some of these functions are defined by the game client, but others are defined
inthegamesFrameXMLcode.
FrameXML Functions
The code for the default user interface includes definitions for a number of
utility functions. Although they may not be considered APIs in the strictest
sense, their usage is consistent enough with true API functions that they
deserve documentation here. For example, consider the definition of the
TakeScreenshot function:
function TakeScreenshot()
if ( ActionStatus:IsShown() ) then
ActionStatus:Hide();
end
Screenshot();
end
This function is designed to make it easier to take screenshots programmat-
ically. Normally after you take a screenshot the ‘‘Screen Captured’’ message is
displayed. This function hides that text so you can take multiple screenshots
in quick succession.
The most unique characteristic of FrameXML-defined functions is that you
can examine their inner workings. All of the APIs mentioned so far are hidden
behind the Lua-C interface. You can call the functions from Lua and use the
values they return, but in general there is no way to know exactly how they
operate.
Protected Functions
Early in WoW’s life, addons had free reign over all functions available in the
API. Some of these functions included movement control, combat activities,
190 Part II Programming in World of Warcraft
and other features the designers have since deemed inappropriate for addons.
That early leeway made it relatively trivialespecially with a bit of help from
external programsto write ‘‘grinding bots’’ that would completely control
your character while you went to the movies. Set it up before work and by the
time you got home you could have gained a few levels and received massive
amounts of loot to sell.
A similar problem were ‘‘button masher’’ addons like Emergency Monitor
and Decursive. A player could repeatedly press a single key or mouse button
and the addon would do all the decision-making: who to target, what spell to
cast, and so on.
Subsequent patches removed these capabilities by marking the offending
functions as protected. Protected functions can be called only by built-in code.
In addition there is another class of functions that are only protected during
combat. WoW is able to tell when the running code is from an addon or macro
versus a built-in file, so it can prevent the protected function from running in
those cases. Table 11-2 describes a small sampling of protected functions to
give you an idea of their nature.
Table 11-2: Sample of Protected Functions
FUNCTION DESCRIPTION
Jump Causes the character to jump
CastSpellByName Attempts to cast the given spell
ToggleAutoRun Controls the character’s auto-run
TargetUnit Targets the specified unit
PetAttack Sends your pet to attack
RegisterUnitWatch Registers a frame to be shown/hidden based on a unit
These are just examples. All movement, targeting, ability use, and action bar
manipulation functions are completely protected. The API reference section in
Chapter 27 shows which functions are protected, so you know whether or not
you can call them.
NOTE You may be wondering how it is possible to write an action bar or unit
frame addon at this point, considering that spell-casting and targeting functions
are protected. This problem is resolved by using secure templates, which are
covered in Chapter 15.
Unit Functions Up Close
The first logical grouping of APIs to examine is unit functions. As previously
mentioned, these functions expose data about players, mobs, and NPCs. Most
Chapter 11 Exploring the World of Warcraft API 191
of the functions are quite simple; they take in one or two unit IDs and return
some information to the calling code. Table 11-3 shows a few of the different
unit functions.
Table 11-3: Example Unit Functions
UNIT FUNCTION DESCRIPTION
exists =
UnitExists(unit)
Returns 1if the unit exists, nil otherwise. For example,
UnitExists(“target“) returns 1only if you have a
target selected. Many of the other unit functions return
nil if UnitExists is nil.
name, realm =
UnitName(unit)
Returns the name of the specified unit. If the unit is a
player in a cross-realm battleground, the second return is
the server name, otherwise it is nil.
level =
UnitLevel(unit)
Returns the level of the unit or –1 if you’re not supposed
to know the level (special bosses, enemy players more
than 10 levels above you).
reaction =
UnitReaction(unit,
otherUnit)
Determines the reaction of unit to otherUnit. Returns
a number from 17, where 1is extremely hostile, 7is as
friendly as possible, and nil is returned if unknown.
health =
UnitHealth(unit)
Returns the health of the unit. For the player, the player’s
pet, party/raid members, and their pets, health is the
absolute number of hit points. All other units return a
percentage from 0100.
mana =
UnitPower(unit[,
powerType)
Same as UnitHealth but for mana, rage, energy, and
focus (collectively referred to as mana throughout the
API). By default this function returns the current power
type that unit is using, but you can specify a second
argument to query another power type (for example, the
mana of a druid who is shapeshifted).
healthMax =
UnitHealthMax(unit)
Returns the maximum health of the unit (actual number
of hit points or 100 depending on the same criteria as
UnitHealth).
manaMax =
UnitManaMax(unit)
Same as UnitHealthMax but for mana.
Each of these functions takes in unit IDs that follow a very simple pattern.
A unit ID can be one of the tokens listed in Table 11-4 with either pet added
to the end, or possible target included an arbitrary number of times. For
example, party1target shows the target of your first party member, and
party2pettarget represents the target of your second party member’s pet.
Additionally, the WoW client will accept the name of a party or raid member
as a unit ID. These unit ID tokens are not case-sensitive.
192 Part II Programming in World of Warcraft
NOTE Not every function will work correctly on all unit IDs. The documentation
in Chapter 27 explains those cases.
Table 11-4: Base Unit IDs
UNIT ID REFERS TO...
player The character controlled by the player.
pet The player’s pet.
Vehicle The player’s vehicle.
target The player’s target (equivalent to “playertarget“).
focus The player’s focus target.
mouseover The unit underneath the mouse cursor. Includes characters in the
3-D world and any frame with a set unit attribute.
partyN The Nthparty member where Nis a number from 14. None of the
party unit IDs refers to the player.
partypetN The Nthparty member’s pet.
raidN The Nthraid member where Nis a number from 1to however many
members there are in the raid. The highest Nalways refers to the
player, and the lowest Nalways refers to the raid leader. There is no
correlation between the Nfor raid units and the Nfor party units.
raidpetN The Nthraid member’s pet.
arenaN The Nthenemy in the arena.
npc The currently selected NPC. UnitExists only returns true for this
unit while you are interacting with an NPC (that is, when you are
turning in a quest, using a vendor, and so on).
none No unit. It was created to allow activation of the target selection
cursor even when you are targeting something vulnerable to the
spell you are casting.
In addition to these token-based unit IDs, most functions will accept the
name of a party or raid member. For example, if you have a party member
called ‘‘Healadin’’ you could query his health by running:
/run print(UnitHealth(“Healadin“))
Chapter 11 Exploring the World of Warcraft API 193
Querying Item Information for BagBuddy
To get the information you need for BagBuddy, you have to access three
different (but related) API systems:
Container APIProvides information about your bags, and the items in
your bags.
Item APIProvides various information about specific game items.
Inventory APIProvides information about the items the player cur-
rently has equipped.
In this section, you implement a simple function that scans your bags for
items, then sorts them and displays them in the BagBuddy frame. Later, you
extend this update function to allow for filtering of items based on name
and rarity.
Scanning Bags with the Container API
Start with an example function that can scan the player’s bags for empty slots.
Run the following code snippet in-game:
local freeSlots = 0
for bag = 0, NUM_BAG_SLOTS do
for slot = 1, GetContainerNumSlots(bag) do
local texture = GetContainerItemInfo(bag, slot)
if not texture then
freeSlots = freeSlots + 1
end
end
end
print(“You have“, freeSlots, “free slots in your containers.“)
This container API uses bag IDs and slot IDs. A bag ID can be any of the
following values:
0The player’s backpack
1The player’s first bag (from the right)
2The player’s second bag (from the right)
3The player’s third bag (from the right)
4The player’s fourth bag (from the right)
194 Part II Programming in World of Warcraft
In the future, WoW may add more bag slots, so when you iterate
over the bags in the preceding snippet, start at 0and go through to
NUM_BAG_SLOTS. Because each bag might have a different number of slots,
you use the GetContainerNumSlots() function to query the max number
of slots. This function takes in a bag ID and returns the number of slots in
that bag.
The second (inner) loop goes through each slot in the bag and uses the
GetContainerItemInfo() function to query information about the item in the
given slot. In this case, the function returns the following information:
textureThe path to the icon texture for the item.
countThe number of items in the stack at the given container slot.
lockedIndicates if the item is currently locked (such as when the item
has been dragged to a mail slot, or the trade window).
qualityA number representing the quality/rarity of the item.
readableIndicates if the item can be read; for example, a book or scroll.
lootableIndicates if the item can be looted; for example, a chest or
clam that can be opened.
linkA hyperlink for the item in a given slot that can be passed to the
item functions for more information.
If the slot does not contain an item, texture (the first return) will be nil.
You can check it to easily see if the slot contains an item. The preceding
snippet checks to see if this value is missing, and counts it as a free slot if
that’s the case. Although there is an easier function to obtain this informa-
tion, GetContainerNumFreeSlots(), you’ll be using the same type of loop in
BagBuddy.
Querying Detailed Item Information
You get quite a bit of information from the container API, but you can’t get
other basic information such as the item’s name. For that, you need to utilize
the item API. It enables you to get the following information about an item
(among other details):
The item’s name.
The item’s rarity.
The maximum stack size for the given item.
Thesalepriceoftheitematavendor.
The level required to use the item.
Chapter 11 Exploring the World of Warcraft API 195
Item Identifiers
To use the item API, you need some way to specify the item you’d like to
query. You could simply specify the item name, but due to names not being
completely unique, this only works when the item is in the player’s inventory
or containers. The more specific form allows you to specify the numeric item
ID, or an item’s hyperlink or item string.
Numeric Item ID
Each item in World of Warcraft is uniquely identified by a numeric ID.
Table 11-5 shows a list of common items and their item IDs. Notice that some
of the names are the same, whereas the IDs are distinct.
Table 11-5: Sample Mapping Between Items and Item IDs
ITEM NAME ITEM ID
Hearthstone 6948
Insignia of the Alliance 18864
Insignia of the Alliance 29593
Militia Dagger 2224
The first Insignia of the Alliance item is the class-specific insignia for
Paladins. The second is the Shaman-specific trinket. Although they no longer
have different effects, they remain distinct items as far as WoW is concerned.
Another advantage to utilizing item IDs instead of names is that the lookup
will work correctly regardless of what locale client the player is using. If you
try to look up an item with its English name on a French client, it will not work
correctly.
In addition, the database sites for World of Warcraft (including WoW
Armory) use these IDs. For example, the URL to access information about the
Militia Dagger is http://www.wowarmory.com/item-info.xml?i=2224.
Item Strings
A problem with using just item IDs is that they don’t include any information
about a specific instance of an item. Say you have a pair of gloves that is
enchanted with Enchant Gloves - Gatherer, an enchantment that gives you
+5 skill in Mining, Herbalism, and Skinning. When you query the item by
numeric ID, it will not include the enchantment. An item string combines the
item ID with this information, and consists of the string item: followed by
nine different numeric values, separated with colons. Table 11-6 shows the
different values included in the string.
196 Part II Programming in World of Warcraft
Table 11-6: Components of Item Strings
NAME DESCRIPTION
itemID The numeric item ID.
enchantID A numeric identifier representing the permanent item enchantment.
jewelID1 A numeric identifier indicating a socketed gem in the given item.
jewelID2 See above.
jewelID3 See above.
jewelID4 See above.
suffixID A numeric suffix identifier. This is how the game differentiates
between an item that is ‘‘of the Monkey’’ and ‘‘of the Whale.’’
uniqueID Information pertaining to a specific instance of an item, such as who
crafted it or how many charges are left on a multi-charge item. The
specific meaning of these numbers is unclear, and appears to be
something generated and used by Blizzard on the server end of the
game.
linkLevel The level of the character supplying the link. This is used by the new
Heirloom items to calculate the correct item tooltips.
Like most things in the WoW API, examples tend to make a bit more sense.
The following is a list of example item strings, and the information they
contain:
item:6948:0:0:0:0:0:0:0:0Hearthstone with no additional informa-
tion about stats, creator, or level.
item:10042:0:0:0:0:0:614:0:0Cindercloth Robe with a suffix ‘‘of the
Monkey’’ that adds +11 Agility and +11 Stamina.
item:42992:0:0:0:0:0:0:0:45Discerning Eye of the Beast, the heir-
loom mana trinket, shown scaled to level 40.
item:41319:3842:3642:3466:0:0:0:0:80Hateful Gladiator’s Kodo-
hide Helm with +30 Stamina +25 Resilience enchantment, and a gem
that provides +32 Stamina and Stun Duration Reduced by 10 and a +9
Spell Power and +12 Stamina gem.
As you can see, any values not provided at the end default to 0. This means
you can avoid specifying the item level or unique id if you don’t have that
information (or simply specify that they are 0).
Item Hyperlinks
Once you understand the format of an item string, creating an item hyperlink
is very easy. A hyperlink, in general, consists of the following format:
|H<DATA>|h<DISPLAYTEXT>|h
Chapter 11 Exploring the World of Warcraft API 197
The pipe (|) character is used in World of Warcraft as an escape character,
much like Lua itself uses the backslash (\). The hyperlink begins with a |H,
followed by the data for the hyperlink. In the case of item links, this is just the
item string itself. The data ends with |h, followed by the text that is actually
displayed in the hyperlink, including the left and right brackets. The hyperlink
ends with a final |h. To color the link, you can wrap it using color codes.
For example, a script that can print a hyperlink for your Hearthstone might
look like this:
print(“|cffffffff|Hitem:6948:0:0:0:0:0:0:0:0|h[Hearthstone]|h|r“)
The color code for white is specified, the hyperlink data is included, and the
text of the link itself follows. You may encounter different types of hyperlinks
in your exploration of the WoW API, but you won’t find yourself creating
them very often. More often than not, when you need a hyperlink you simply
query the API and use whatever is returned.
Using the Item API
Once you have an item identifier, the item API is simple to use. In particular
you are concerned with the GetItemInfo() function, which takes in such an
identifier and returns the following:
nameThe name of the item.
linkA hyperlink for the item.
qualityQuality (rarity) level of the item.
iLevelInternal level of the item.
reqLevelMinimum character level required to use or equip the item.
classLocalized name of the item’s class/type.
subclassLocalized name of the item’s subclass/subtype.
maxStackMaximum stack size for the item (that is, largest number of
items that can be held in a single bag slot).
equipSlotNon-localized token identifying the inventory type of the
item.
texturePathtoanicontexturefortheitem.
vendorPricePrice an NPC vendor will pay to buy the item from the
player.
We are only concerned with the item’s name, which is the first return from
the function. You will use this to sort the items once you’ve finished scanning.
To prevent against item scanning, where someone tries to get information
about items that aren’t yet in the game, this function returns only information
about those items that the player has seen. In particular, the item must exist in
the player’s local item cache.
198 Part II Programming in World of Warcraft
Writing a Bag Scanner
You can put together the different APIs to update BagBuddy to actually display
the player’s inventory. Open BagBuddy.lua and add the following function
definition at the end of the file:
function BagBuddy_Update()
local items = {}
-- Scan through the bag slots, looking for items
for bag = 0, NUM_BAG_SLOTS do
for slot = 0, GetContainerNumSlots(bag) do
local texture, count, locked, quality, readable, lootable, link =
GetContainerItemInfo(bag, slot)
if texture then
-- If found, grab the item number and store other data
local itemNum = tonumber(link:match(“|Hitem:(%d+):“))
if not items[itemNum] then
items[itemNum] = {
texture = texture,
count = count,
quality = quality,
name = GetItemInfo(link),
link = link,
}
else
-- The item already exists in our table, just update the count
items[itemNum].count = items[itemNum].count + count
end
end
end
end
end
This function goes through all of the player’s bag slots and checks to see if
the slot is empty or not. For each item it finds, it parses the item link to get the
item number and then stores the following information in a table:
The path to the item’s icon texture.
The number of items in the stack.
The quality number for the item.
The item’s name.
The item’s link.
You use the item number rather than the name because it enables you to
differentiate between different items that share a name. You could use the item
link, but the uniqueID component of the link may be different (for example, if
the items were crafted by two different people). If you used the item link, the
items would appear to be different.
Chapter 11 Exploring the World of Warcraft API 199
If (during the loop) you encounter an item that you’ve already added to the
table, you simply increment the item’s count in the table entry that has already
been stored.
Sorting the Player’s Inventory
To ensure the inventory is displayed in a consistent order, you will sort them
by name. Add the following function definition somewhere before the update
function:
local function itemNameSort(a, b)
return a.name < b.name
end
This function simply takes in two tables that are being compared, and
compares the names of the items. Now you can use the function by adding the
following to BagBuddy_Update(), at the end of the function:
local sortTbl = {}
for link, entry in pairs(items) do
table.insert(sortTbl, entry)
end
table.sort(sortTbl, itemNameSort)
This code simply loops over all of the stored items, and adds each entry to
a new temporary table. Then you call table.sort(), passing in your sorting
function to do the heavy lifting.
Displaying the Inventory
Now that you have a sorted list of inventory items, you can write some
code to display them in the BagBuddy frame. Add the following to
BagBuddy_Update(), after the sorting and before the end of the function:
-- Now update the BagBuddyFrame with the listed items (in order)
for i = 1, 24 do
local button = BagBuddy.items[i]
local entry = sortTbl[i]
if entry then
-- There is an item in this slot
button.icon:SetTexture(entry.texture)
if entry.count > 1 then
button.count:SetText(entry.count)
button.count:Show()
else
button.count:Hide()
end
if entry.quality > 1 then
button.glow:SetVertexColor(GetItemQualityColor(entry.quality))
200 Part II Programming in World of Warcraft
button.glow:Show()
else
button.glow:Hide()
end
button:Show()
else
button:Hide()
end
end
Because you already know you have 24 buttons in the frame, simply loop
over each of them. You also have a list of items that are sorted in order, so you
know that the first item in the list should be displayed in the first button.
A lot happens on each iteration of the loop. First you check to see if there is a
corresponding item in the list. If there isn’t you just hide the button. Otherwise
you first set the item’s icon texture. If there are multiple items with the same
item number, you update the item count font string. Finally, you check the
quality of the item. If the quality is greater than one (that is, the item is green,
blue, purple, or higher), you shade the glow texture to the appropriate color,
obtained with the GetItemQualityColor() function.
This function takes in a quality index, and returns the red, green, and blue
color components (between 0.0 and 1.0). These can then be passed into any
of the functions that accept colors in that form, such as the texture method
SetVertexColor(). The different quality indices are listed in Table 11-7.
Table 11-7: Item Quality Indices
INDEX DESCRIPTION COLOR EXAMPLE ITEM
0 Poor Grey Broken I.W.I.N. Button
1 Common White Archmage Vargoth’s Staff
2 Uncommon Green X-52 Rocket Helmet
3 Rare or Superior Blue Onyxia Scale Cloak
4 Epic Purple Talisman of Ephemeral Power
5 Legendary Orange Fragment of Val’anyr
6 Artifact or Heirloom Light Yellow Bloodied Arcanite Reaper
Testing the Update Function
You haven’t set anything up to call the function, but you can call it manually
by running the following code in-game:
/run BagBuddy_Update()
Figure 11-1 shows BagBuddy after running the update function. The items
are all sorted by name, and multiple items are combined into a single virtual
Chapter 11 Exploring the World of Warcraft API 201
stack. Any item that is higher than common quality glows to show the familiar
rarity colors (this will be hard to see in the figure). The frame shows only the
first 24 items, or less if you don’t have that many items in your inventory.
Figure 11-1: BagBuddy showing a sorted inventory
Finding the Right API Functions
ThemostdifcultpartwhenstartingtoworkwiththeWorldofWarcraftAPI
is finding the right function or event (which you’ll learn about in Chapter 13).
Although we would love to provide a simple guide that tells you what
functions and events to use for any situation, the API consists of more than
1,900 functions and 530 events. Any guide would be incredibly large, and near
impossible to write. Instead we hope to give you a set of guidelines that you
can use to find the right functions.
Exploring the API Categories
This book contains a chapter that lists a number of different categories, and the
functions that belong to the given group. This is a good place to start if you’re
looking to better understand a portion of the API. Be aware that many functions
are listed in multiple categories. The same reference is available (and kept
up-to-date) online at http://wowprogramming.com/docs/api categories.
Although it does not always contain an updated list of available func-
tions, the World of Warcraft API listing at WoWWiki (http://wowwiki
.com/World of Warcraft API) lists functions by various categories as well.
202 Part II Programming in World of Warcraft
Examining the FrameXML Code
A useful question whenever you are trying to accomplish something in a
custom addon is to ask:
‘‘Does the default user interface do this?’’
Ifso,thensomewhereinthecodeforthedefaultUIisthetechniqueused
to accomplish the task; it’s just a matter of finding it. For example, you might
want to display the player’s haste rating and percentage effect somewhere
in your addon. A quick look at the API categories doesn’t reveal anything
immediately so you instead look at the default user interface.
That information is displayed on the character panel in the stats section
at the bottom. To find out where that panel is defined, you can do a bit
of investigative work. Start by running the /framestack command that was
introduced in Chapter 9. From the information you get there, it appears that
PaperDollFrame and CharacterFrame are both good candidates. Conveniently
enough, these frames are defined in files by the same name in the FrameXML
code.
Opening CharacterFrame.xml shows you the definition of the different
tabs, so it appears that that’s the outmost frame that contains the sub-
frames. The CharacterAttributesFrame in PaperDollFrame.xml, however,
looks like a good candidate. Now that you’ve found the frame, you can open
PaperDollFrame.lua to look around.
At the top of the file you see a number of global constants defined. Looking
for one having to do with haste, you find the following constants:
CR_HASTE_MELEE = 18;
CR_HASTE_RANGED = 19;
CR_HASTE_SPELL = 20;
When haste was first introduced in the game, there were different versions
for melee, ranged, and spell. In Wrath of the Lich King they were all combined
into a single haste rating. Pick the melee version and search for that throughout
the whole file.
The only instance in the file is in the following line of code, in the aptly
named PaperDollFrame_SetAttackSpeed() function:
statFrame.tooltip2 = format(CR_HASTE_RATING_TOOLTIP, i
GetCombatRating(CR_HASTE_MELEE), GetCombatRatingBonus(CR_HASTE_MELEE));
Now you can test these two functions to see if they work for your needs.
Run the following code in-game:
/run print(GetCombatRating(CR_HASTE_MELEE))
/run print(GetCombatRatingBonus(CT_HASTE_MELEE))
You will find that although the returns from GetCombatRating() are the
same, you may have different results for the actual percent bonus. This bonus
Chapter 11 Exploring the World of Warcraft API 203
could depend on any number of factors, and you’ll want to take that into
consideration when using it in your addon.
Looking at Another Addon
If you can’t find a place in the default user interface that does what you want,
but know that other addons somehow accomplish it, you can always look at
the other addon. When doing this, keepinmindthatthecodewewriteas
authors is not completely open for copying. When in doubt, you may find it
useful to contact the author to see how he’s done something and ask if you can
useasimilarmethodinyourownaddon.
Of course, sometimes it’s just a simple as finding the right function, which
you can then just use directly in your own addon.
Asking for Help!
Each situation will be slightly unique, so it’s always useful to ask for help
when working on your own addon. A number of websites, forums, and chat
rooms support addon development for World of Warcraft (see Appendix D
for more information). When asking for help, we suggest the following:
When initially presenting your problem, try to explain what you are
trying to accomplish instead of how you are trying to accomplish it.
This gives the people who are helping you a chance to understand the
problem without getting caught up in a specific way of doing it. This can
sometimes reveal a much nicer solution to the problem.
Provide as much code as possible and indicate the areas that are having
problems. Posting 10 lines of code out of a 300-line function makes it very
difficult to see what is happening. You can post large bits of code on sites
like http://pastey.net and http://pastebin.com.
If you are getting an error, give the specific error text, and post the code
involved in the error.
Be patient! Not everyone is always waiting around to pounce on a new
question. You should continue to explore in your own time, and hopefully
someone will be able to help you.
Summary
This chapter introduced you to APIs in the general sense, and gave you
a specific example of how to use the item and container API to access
information about the player’s containers and items. Understanding the way
these functions interact with the game is essential to creating effective addons
that accomplish a variety of goals.
204 Part II Programming in World of Warcraft
The Code
BagBuddy.lua
function BagBuddy_OnLoad(self)
SetPortraitToTexture(self.portrait, i
“Interface\\Icons\\INV_Misc_EngGizmos_30“)
-- Create the item slots
self.items = {}
for idx = 1, 24 do
local item = CreateFrame(“Button“, “BagBuddy_Item“ .. idx, i
self, “BagBuddyItemTemplate“)
self.items[idx] = item
if idx == 1 then
item:SetPoint(“TOPLEFT“, 40, -73)
elseif idx == 7 or idx == 13 or idx == 19 then
item:SetPoint(“TOPLEFT“, self.items[idx-6], i
“BOTTOMLEFT“, 0, -7)
else
item:SetPoint(“TOPLEFT“, self.items[idx-1], i
“TOPRIGHT“, 12, 0)
end
end
end
local function itemNameSort(a, b)
return a.name < b.name
end
function BagBuddy_Update()
local items = {}
-- Scan through the bag slots, looking for items
for bag = 0, NUM_BAG_SLOTS do
for slot = 0, GetContainerNumSlots(bag) do
local texture, count, locked, quality, readable, i
lootable, link = GetContainerItemInfo(bag, slot)
if texture then
-- If found, grab the item number and store other data
local itemNum = tonumber(link:match(“|Hitem:(%d+):“))
if not items[itemNum] then
items[itemNum] = {
texture = texture,
count = count,
quality = quality,
name = GetItemInfo(link),
link = link,
}
else
Chapter 11 Exploring the World of Warcraft API 205
-- The item already exists in our table, update count
items[itemNum].count = items[itemNum].count + count
end
end
end
end
local sortTbl = {}
for link, entry in pairs(items) do
table.insert(sortTbl, entry)
end
table.sort(sortTbl, itemNameSort)
-- Now update the BagBuddyFrame with the listed items (in order)
for i = 1, 24 do
local button = BagBuddy.items[i]
local entry = sortTbl[i]
if entry then
-- There is an item in this slot
button.icon:SetTexture(entry.texture)
if entry.count > 1 then
button.count:SetText(entry.count)
button.count:Show()
else
button.count:Hide()
end
if entry.quality > 1 then
button.glow:SetVertexColor( i
GetItemQualityColor(entry.quality))
button.glow:Show()
else
button.glow:Hide()
end
button:Show()
else
button:Hide()
end
end
end
CHAPTER
12
Interacting with Widgets
You’ve already created the base frame for BagBuddy, and added graphics,
text, and item buttons created using templates. However, other than the
highlight texture on the item buttons, the frames are entirely static and you
can’t really interact with them. In this chapter you learn about different types
of frames, such as buttons, status bars, and edit boxes. Once you’ve created
new frames, you learn how to add dynamic behavior to them.
Each different type of frame widget in World of Warcraft has certain scripts
that can be set to respond to changes. For example, a button can set an OnClick
scripttoruncodewhenthebuttonisclicked,orOnEnter to do something
when the mouse moves over the button. Other more complex widgets, such as
edit boxes, allow you to respond to different types of key presses.
This chapter is meant as an introduction to interacting with widgets; for
a full listing of the available frame scripts and methods, please refer to the
Widget Reference in Chapter 29.
Making BagBuddy’s Buttons Interactive
The most often used widget (other than the basic frame type) is a Button.
Buttons are used all over the default user interface to accomplish different
types of tasks:
Player, target, and other unit frames
Action buttons
Buff and debuff icons
207
208 Part II Programming in World of Warcraft
Dropdown (selection) menus
Menu buttons
In BagBuddy you will use buttons for the rarity filters and the close button
in the top-right corner of the frame, in addition to the already created item
buttons. Let’s start exploring interactive widgets by setting OnEnter and
OnLeave scripts for the item buttons.
Setting Frame Scripts via XML
You can add a frame script to an XML definition by adding a <Scripts>
tag with one or more script definitions inside. Add the following code to
the definition of BagBuddyItemTemplate,afterthe</Layers> tag but before the
<NormalTexture> tag:
<Scripts>
<OnEnter>
print(“Mouse has entered“, self:GetName())
</OnEnter>
<OnLeave>
print(“Mouse has left“, self:GetName())
</OnLeave>
</Scripts>
If you load up the game, you should be able to run your mouse over any of
the item buttons, and the game will display a message for each of the different
scripts. The output may look similar to the following:
Mouse has entered BagBuddy_Item6
Mouse has left BagBuddy_Item6
Mouse has entered BagBuddy_Item20
Mouse has left BagBuddy_Item20
This is one of two ways to set frame scripts using XML. For each type of
script, you simply write code that is then compiled to a function and run in
response to that widget event. Each different type of script handler is passed
certain arguments; you can see that the variable self is used here, which isn’t
explicitly defined.
The OnEnter and OnLeave scripts are passed two different arguments:
selfThe button that the mouse has just entered.
motionA Boolean flag indicating if the event was caused by the mouse
moving over the frame. When this value is false, the frame being
shown while the mouse is already over its position may have caused
the event.
Chapter 12 Interacting with Widgets 209
Using the function Attribute
We prefer to avoid writing any code directly in XML files because keeping
the frame definition code separate from any behavior code makes it easier to
maintain addon code. To do this, you can create your functions in BagBuddy.lua
and assign them directly in the XML using the function attribute. Replace the
<Scripts> section you wrote in the last section with the following:
<Scripts>
<OnEnter function=“BagBuddy_Button_OnEnter“/>
<OnLeave function=“BagBuddy_Button_OnLeave“/>
</Scripts>
Now open BagBuddy.lua and add the following two functions somewhere
in the file:
function BagBuddy_Button_OnEnter(self, motion)
print(“Mouse has entered“, self:GetName())
end
function BagBuddy_Button_OnLeave(self, motion)
print(“Mouse has left“, self:GetName())
end
Because you’re writing your own functions, you need to specify the argu-
ments to access them; other than that, the functions are the same.
Setting Frame Scripts Using Lua
As with most things dealing with the frame system in World of Warcraft,
frame scripts can be set using Lua instead of XML. This is accomplished using
the SetScript() method for frames. If you include the function definitions
for BagBuddy_Button_OnEnter and BagBuddy_Button_OnLeave,youcouldjust
add the following to the end of the BagBuddy_OnLoad function:
for idx, button in ipairs(self.items) do
button:SetScript(“OnEnter“, BagBuddy_Button_OnEnter)
button:SetScript(“OnLeave“, BagBuddy_Button_OnLeave)
end
It doesn’t make much sense to structure your code this way when you’re
using a frame template. With a different type of addon, though, you might
need to set scripts in this way, so it’s good to know the possibility exists.
Using the SetScript() method is the only way to clear an existing script
from a frame. To accomplish this, you simply pass nil as the second argument.
210 Part II Programming in World of Warcraft
Showing Item Tooltips Using OnEnter and OnLeave
Having the item buttons print something to the chat window is great, but
it’s not very useful; instead you can display the item’s tooltip. You can
accomplish this using the GameTooltip object provided by the default user
interface. Figure 12-1 shows the tooltip for the Death Knight spell Blood
Presence.
Figure 12-1: GameTooltip showing tooltip for Blood Presence
To show a tooltip, you typically use the following process:
1. Call the GameTooltip:SetOwner() method, passing in the frame object
that will temporarily own the tooltip, a string that tells the system how
to anchor the tooltip, and optionally a set of offsets.
2. Call one of the many Set methods to tell the tooltip what information to
display. In this case, you’ll use the SetHyperlink method, passing in the
item hyperlink.
3. Show the tooltip by calling GameTooltip:Show().
But first you need to store the item link in a place where the script handler
can access it. Open BagBuddy.lua and change the update loop at the end
of BagBuddy_Update() to the following (the highlighted lines are the only
changes):
for i = 1 , 24 do
local button = BagBuddy.items[i]
local entry = sortTbl[i]
if entry then
-- There is an item in this slot
button.link = entry.link
button.icon:SetTexture(entry.texture)
Chapter 12 Interacting with Widgets 211
if entry.count > 1 then
button.count:SetText(entry.count)
button.count:Show()
else
button.count:Hide()
end
if entry.quality > 1 then
button.glow:SetVertexColor(GetItemQualityColor(entry.quality))
button.glow:Show()
else
button.glow:Hide()
end
button:Show()
else
button.link = nil
button:Hide()
end
end
During the iteration of the loop, you just update the link key in the frame
table using the link stored in the item entry. If there isn’t an item to display
the button, you clear the value from the frame table. Next, you need to
update the script handler functions. Replace the definitions of the OnEnter and
OnLeave handlers with the following:
function BagBuddy_Button_OnEnter(self, motion)
if self.link then
GameTooltip:SetOwner(self, “ANCHOR_TOPRIGHT“)
GameTooltip:SetHyperlink(self.link)
GameTooltip:Show()
end
end
function BagBuddy_Button_OnLeave(self, motion)
GameTooltip:Hide()
end
In the OnEnter handler, you first check to see if the button is set to display
an item. Then you tell the tooltip to anchor itself to the top right of the item
button, and set it to display the item. The corresponding OnLeave script simply
hides the tooltip.
If you load the addon and run the BagBuddy_Update() function, you should
be able to mouse over the items in BagBuddy to display item tooltips.
Figure 12-2 shows one such tooltip.
212 Part II Programming in World of Warcraft
Figure 12-2: BagBuddy showing an item tooltip OnEnter
Adding Clickable Buttons to BagBuddy
Although you eventually will make the item buttons clickable to use, that
is a protected action and is a bit more complicated than just setting a script
handler. However, you don’t need to do anything special to create a close
button and a set of filter buttons.
Introducing the OnClick Handler
The Button frame type can register to receive mouse clicks. World of War-
craft recognizes several different mouse buttons, calling the default ones
LeftButton,RightButton,MiddleButton,Button4,andButton5.Thereare
some computer mice that have more than five buttons, and these continue as
Button6,Button7, etc. Which physical button on your mouse corresponds to
a given button name is between your operating system and the WoW client.
In addition to different mouse buttons, you can register for either the click
portion or the release portion of the click.
To register for mouse clicks, you must call the RegisterForClicks() method.
This function accepts a list of strings, each indicating a type of click you would
like to register for. By default, all buttons are registered for the LeftButtonUp
click, which is the release portion of a left button click. The following are all
valid:
LeftButtonUp
MiddleButtonDown
Button4Up
AnyUp
AnyDown
Chapter 12 Interacting with Widgets 213
The last two are special buttons that register automatically for all release
button clicks and down button clicks, respectively.
Once you’ve registered for clicks, you can set an OnClick script on the frame
to receive the click events. When the client calls an OnClick handler, it passes
the following arguments:
selfThe frame object that the handler was called for.
buttonA string indicating which mouse button was used to click the
frame.
downA Boolean flag indicating if the mouse click was triggered by a
downward click, rather than the releasing of a click.
You can run the following code in-game to play with the different mouse
buttons and the release/press portions of a click. Click the game button with
multiple buttons on your mouse to see the differences between them. Also,
click and hold the button so you can see the difference between the ‘‘up’’ and
‘‘down’’ portions of a click.
if not ClickFrame then
ClickFrame = CreateFrame(“Button“, “ClickFrame“, UIParent, i
“GameMenuButtonTemplate“)
end
ClickFrame:ClearAllPoints()
ClickFrame:SetPoint(“CENTER“, 0, 0)
ClickFrame:SetText(“Click Frame“)
ClickFrame:RegisterForClicks(“AnyUp“, “AnyDown“)
ClickFrame:SetScript(“OnClick“, function(self, button, down)
local name = self:GetName()
print(name, button, down)
end)
You should see a line of output added to your chat frame showing the name
of the frame, ClickFrame, and the button that was clicked along with whether
or not the click captured was on the release of the click.
Creating a Close Button Using Templates
Because almost every window in the default user interface has a close button,
naturally there is a template you can use to save some time. After the </Layers>
tag in the definition for BagBuddy, add the following definition:
<Frames>
<Button name=“$parent_Close“ parentKey=“close“ i
214 Part II Programming in World of Warcraft
inherits=“UIPanelCloseButton“>
<Anchors>
<Anchor point=“TOPRIGHT“>
<Offset x=“-30“ y=“-8“/>
</Anchor>
</Anchors>
</Button>
</Frames>
The template already includes the code that is used to actually hide the
frame. The template is defined in UIPanelTemplate.xml:
<Button name=“UIPanelCloseButton“ virtual=“true“>
<Size>
<AbsDimension x=“32“ y=“32“/>
</Size>
<Scripts>
<OnClick>
HideParentPanel(self);
</OnClick>
</Scripts>
<NormalTexture file=“Interface\Buttons\UI-Panel-MinimizeButton-Up“/>
<PushedTexture file=“Interface\Buttons\UI-Panel-MinimizeButton-Down“/>
<HighlightTexture
file=“Interface\Buttons\UI-Panel-MinimizeButton-Highlight“
alphaMode=“ADD“/>
</Button>
When the button is clicked, the HideParentPanel() function is called with
the frame passed as the first argument. This function is defined in UIParent.lua
and is simply a short function that quickly looks up the parent frame, and then
hides it.
Creating Clickable Filter Buttons
You are going to create seven different buttons that can be used to filter
items by their rarity, shown in Figure 12-3. Because you already have a
template that contains more than what you need, you can just inherit from
BagBuddyItemTemplate and ignore the count text and glow texture, or you
could define a new template. In this case, you’ll choose to re-use the existing
template, making your code much shorter. Add the following template defi-
nition following the item template definition, but before the code for the main
BagBuddy frame:
<CheckButton name=“BagBuddyFilterTemplate“ i
inherits=“BagBuddyItemTemplate“ virtual=“true“>
<Scripts>
Chapter 12 Interacting with Widgets 215
<OnEnter function=“BagBuddy_Filter_OnEnter“/>
<OnLeave function=“BagBuddy_Filter_OnLeave“/>
<OnClick function=“BagBuddy_Filter_OnClick“/>
</Scripts>
<CheckedTexture file=“Interface\Buttons\CheckButtonHilight“ i
alphaMode=“ADD“/>
</CheckButton>
Figure 12-3: Filter buttons with filtered inventory
Youdliketobeabletodisplayatooltipwhenthemouseisovertheframe,
so you define new OnEnter and OnLeave scripts in the template. These scripts
overwrite the original definitions from BagBuddyItemTemplate, which is very
useful.
You may also have noticed that the Button tag is changed to a CheckButton
tag. That gives you access to the GetChecked() method, which enables you
to see if the button is currently selected. There is also SetChecked() method,
but you won’t need to use it in this addon. The state of the button changes
automatically when the user clicks it, so all you need to do is check to see if
it’s actually set in your OnClick handler.
Finally, you set the CheckedTexture for the button. This is a special texture
for check buttons that is shown when the button is selected, and is hidden
otherwise. In this case it’s just a highlight around the edge of the button that
should indicate this state.
216 Part II Programming in World of Warcraft
Creating the Filter Buttons Dynamically
Now you must create the filter buttons, and you’ll do this dynamically in the
OnLoad function where you’re doing other initialization. At the bottom of the
function, add the following code:
-- Create the filter buttons
self.filters = {}
for idx=0,5 do
local button = CreateFrame(“CheckButton“, “BagBuddy_Filter“ .. idx, i
self, “BagBuddyFilterTemplate“)
SetItemButtonTexture(button, i
“Interface\\ICONS\\INV_Misc_Gem_Pearl_03“)
self.filters[idx] = button
if idx == 0 then
button:SetPoint(“BOTTOMLEFT“, 40, 200)
else
button:SetPoint(“TOPLEFT“, self.filters[idx-1], “TOPRIGHT“, 12, 0)
end
button.icon:SetVertexColor(GetItemQualityColor(idx))
button:SetChecked(false)
button.quality = idx
button.glow:Hide()
end
self.filters[-1] = self.filters[0]
This code first creates a table to store the filter buttons, and then creates
a series of buttons named BagBuddyFilterX, where X is a number between
and including 0 and 5. Each button’s icon is set to a pearl texture, because it’s
white and looks like an orb, so you can easily color it and it’s recognizable.
The first button is anchored specially, but the others are all anchored to the
previous button.
For each button, you use the SetVertexColor() texture method to change
the color of the item being displayed. You call the API function GetItem
QualityColor() to obtain the correct quality color. This gives you six different
glowing colored orbs that indicate the quality color. Next, you uncheck each
filter button using the SetChecked() method,passingfalseinasanargument.
Then you store the quality index in the button table itself. This allows you to
later determine what quality index the button is meant to be filtering for. Next,
you hide the glow texture because you won’t be using it for these buttons.
Finally, you set up a link between the -1 filter and the 0filter. That’s due
to the API that occasionally returns -1 rarity for some items. Figure 12-4 shows
the filter buttons after creation.
Chapter 12 Interacting with Widgets 217
Figure 12-4: BagBuddy rarity filter buttons
Adding Custom Tooltips
You’ve already learned one way to display tooltips for the item buttons, using
the GameTooltip:SetHyperlinkmethod. However, the text you want to display
for the filter buttons isn’t something the game can associate to a game object
(such as a player or an item). Instead, you can use the GameTooltip:SetText()
method to add a line of text directly to the tooltip. Define the following
functions at the bottom of BagBuddy.lua:
function BagBuddy_Filter_OnEnter(self, motion)
GameTooltip:SetOwner(self, “ANCHOR_TOPRIGHT“)
GameTooltip:SetText(_G[“ITEM_QUALITY“ .. self.quality .. “_DESC“])
GameTooltip:Show()
end
function BagBuddy_Filter_OnLeave(self, motion)
GameTooltip:Hide()
end
Global variables are set on every client that can be used to access the
name of the various quality levels. For example, on an English client, ITEM_
QUALITY1_DESC is set to Poor.
Making the Filter Buttons Clickable
Making the buttons actually filter the item results involves two steps. The
first is setting a click handler that triggerstheupdatefunction.Thesecond
step is a bit more complex, and requires changes to the already written update
function. The click handler is relatively simple, so add the following function
to the bottom of BagBuddy.lua:
function BagBuddy_Filter_OnClick(self, button)
BagBuddy.qualityFilter = false
for idx = 0, 5 do
local button = BagBuddy.filters[idx]
if button:GetChecked() then
BagBuddy.qualityFilter = true
end
218 Part II Programming in World of Warcraft
end
BagBuddy_Update()
end
You’ll use BagBuddy.qualityFilter as a Boolean flag that indicates whether
any of the quality filters have been selected. The first thing you do in the OnClick
handler is set this to false. Then you loop through each of the filter buttons
and check if they are set. If any of them are selected, you change the value to
true. Finally, you call the BagBuddy_Update() function to update the results.
Updating the Results
Rather than having you re-type the entire BagBuddy_Update() function, you
can just edit the first main loop, which is responsible for scanning the player’s
bags. The sort and display loops don’t need to change, because they’ll do the
same thing. Replace the scanning loop with the following code:
-- Scan through the bag slots, looking for items
for bag = 0, NUM_BAG_SLOTS do
for slot = 0, GetContainerNumSlots(bag) do
local texture, count, locked, quality, readable, lootable, link = i
GetContainerItemInfo(bag, slot)
if texture then
local shown = true
if BagBuddy.qualityFilter then
shown = shown and BagBuddy.filters[quality]:GetChecked()
end
if shown then
-- If an item is found, grab the item number and store data
local itemNum = tonumber(link:match(“|Hitem:(%d+):“))
if not items[itemNum] then
items[itemNum] = {
texture = texture,
count = count,
quality = quality,
name = GetItemInfo(link),
link = link,
}
else
-- The item already exists in table, just update the count
items[itemNum].count = items[itemNum].count + count
end
end
end
end
end
Chapter 12 Interacting with Widgets 219
You’ve done a bit of restructuring here, adding a variable (shown)thatisset
on each iteration to indicate whether or not the item has passed all the given
filters. This will be useful when you add name filters, but for now it helps you
filter based on quality. The code checks to see if BagBuddy.qualityFilter is
set, and if so checks the filter button to see if it’s selected. If it is, the item
‘‘passes’’ and is added to the items table.
It’s important to note that when no quality filters are selected, all items will
automatically pass this check. Filters are additive, so you can select the Epic
and Rare filters, as shown in Figure 12-5, and all items that match either quality
level will be shown.
Figure 12-5: BagBuddy with the Rare and Epic filters selected
Navigating Multiple Pages
As it stands, BagBuddy displays only the first 24 filtered items in your bags.
Although this might be useful if your bags are small, it doesn’t really work
well with a level 80 character with larger bags. It would be useful to be able to
move between different ‘‘pages’’ of results to find what you need.
To add this feature to BagBuddy, you’ll need to add two more buttons and
a font string. The buttons will be placed in the bottom portion of the frame,
allowing the user to click to go to the next (or previous) page. The font string
will be used to display some status information, such as how many pages of
items match the current filters.
220 Part II Programming in World of Warcraft
Adding XML Definitions for Buttons and Status Text
Open BagBuddy.xml and add the following definitions after the </Button> tag
for the close button, and before the </Frames> tag:
<Button name=“BagBuddy_PrevButton“ parentKey=“prev“>
<Size x=“32“ y=“32“/>
<Anchors>
<Anchor point=“CENTER“ relativeTo=“BagBuddy“ i
relativePoint=“BOTTOMLEFT“>
<Offset>
<AbsDimension x=“50“ y=“150“/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick function=“BagBuddy_PrevPage“/>
</Scripts>
<NormalTexture file=“Interface\Buttons\UI-SpellbookIcon-PrevPage-Up“/>
<PushedTexture
file=“Interface\Buttons\UI-SpellbookIcon-PrevPage-Down“/>
<DisabledTexture
file=“Interface\Buttons\UI-SpellbookIcon-PrevPage-Disabled“/>
<HighlightTexture file=“Interface\Buttons\UI-Common-MouseHilight“
alphaMode=“ADD“/>
</Button>
<Button name=“BagBuddy_NextButton“ parentKey=“next“>
<Size x=“32“ y=“32“/>
<Anchors>
<Anchor point=“CENTER“ relativeTo=“BagBuddy“ i
relativePoint=“BOTTOMRIGHT“>
<Offset>
<AbsDimension x=“-70“ y=“150“/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick function=“BagBuddy_NextPage“/>
</Scripts>
<NormalTexture file=“Interface\Buttons\UI-SpellbookIcon-NextPage-Up“/>
<PushedTexture
file=“Interface\Buttons\UI-SpellbookIcon-NextPage-Down“/>
<DisabledTexture
file=“Interface\Buttons\UI-SpellbookIcon-NextPage-Disabled“/>
<HighlightTexture file=“Interface\Buttons\UI-Common-MouseHilight“ i
alphaMode=“ADD“/>
</Button>
Chapter 12 Interacting with Widgets 221
There shouldn’t be any unfamiliar concepts in these definitions. You use
the previous page and next page buttons from the spellbook interface. Each
button calls a different function when clicked, which is responsible for moving
the page ahead or back. Before you leave the XML file, add the following to the
OVERLAY layer in the XML file, after the definition of the title font string:
<FontString name=“$parent_Status“ parentKey=“status“ i
inherits=“GameFontHighlight“>
<Anchors>
<Anchor point=“CENTER“ relativePoint=“BOTTOM“>
<Offset x=“-10“ y=“150“/>
</Anchor>
</Anchors>
</FontString>
Writing OnClick Handlers for Navigation Buttons
The click handlers for the navigation buttons are quite simple, actually. You’ll
use the BagBuddy.page variable to indicate what page you are on. You’ll make
sure that the previous button is disabled when you’re at the front of the listing,
and the next button when you are at the end. That makes the logic pretty
simple. Add this to the end of BagBuddy.lua:
function BagBuddy_NextPage(self)
BagBuddy.page = BagBuddy.page + 1
BagBuddy_Update(BagBuddy)
end
function BagBuddy_PrevPage(self)
BagBuddy.page = BagBuddy.page - 1
BagBuddy_Update(BagBuddy)
end
The font string and the button enable/disable states will be handled in the
update function itself.
Altering the Update Function for Pages
Surprisingly, the changes you need to make to add page navigation to the
update function are pretty simple. The scan remains the same; you just need
to change the actual update loop. Again, the code is provided in-full, with the
changed lines highlighted.
-- Now update the BagBuddyFrame with the listed items (in order)
local max = BagBuddy.page * 24
local min = max - 23
222 Part II Programming in World of Warcraft
for idx = min, max do
local button = BagBuddy.items[idx - min + 1]
local entry = sortTbl[idx]
if entry then
-- There is an item in this slot
button.link = entry.link
button.icon:SetTexture(entry.texture)
if entry.count > 1 then
button.count:SetText(entry.count)
button.count:Show()
else
button.count:Hide()
end
if entry.quality > 1 then
button.glow:SetVertexColor(GetItemQualityColor(entry.quality))
button.glow:Show()
else
button.glow:Hide()
end
button:Show()
else
button.link = nil
button:Hide()
end
end
Instead of looping through the first 24 items, you’ll use BagBuddy.page to
calculate the maximum item and the minimum item you’ll need to display.
So if you’re on page 2, max is going to be 48 and min is going to be 25. Then
you loop starting at min and working up through to max.Tomakesureyou
get the right button for a given item index, you need to subtract the minimum
number from the current index and add one.
This is because, when on page 2, the fifth item being displayed has an index
in sortTbl of 29. To get the right button number, you take 29, subtract 25
(which is the minimum item index being displayed), and add 1, giving you 5.
There are no other changes to this function.
Enabling and Disabling Navigation Buttons
After you’ve filtered and displayed your items, you should enable and disable
the navigation buttons to ensure they can’t be clicked accidentally. This is
accomplished using the Button:Disable() method, which disables clicking
Chapter 12 Interacting with Widgets 223
functionality and can change the display of the button. Add the following code
after the update loop:
-- Update page buttons
if min > 1 then
BagBuddy.prev:Enable()
else
BagBuddy.prev:Disable()
end
if max < #sortTbl then
BagBuddy.next:Enable()
else
BagBuddy.next:Disable()
end
First you check to see if the minimum item being displayed is greater than
one, and if so you enable the previous button. If the last item being displayed
is less than the last item in the sorted list, then you enable that button. The
buttons are then only disabled when you’re at the start of the list (for previous)
and at the end of the list (for next).
Creating and Updating Status Text
When paging filtered items, it helps to show how many items have been
found so the user can see which page they are on. Add a new font string to
BagBuddy.xml, after the definition of the title font string:
<FontString name=“$parent_Status“ parentKey=“status“ i
inherits=“GameFontHighlight“>
<Anchors>
<Anchor point=“CENTER“ relativePoint=“BOTTOM“>
<Offset x=“-10“ y=“150“/>
</Anchor>
</Anchors>
</FontString>
Now you can update the text after changing the button states. Add the
following code right after the navigation button enable/disable block you’ve
just added in BagBuddy.lua:
-- Update the status text
if #sortTbl > 24 then
local max = math.min(max, #sortTbl)
local msg = string.format(“Showing items %d - %d of %d“, min, max, i
#sortTbl)
BagBuddy.status:SetText(msg)
224 Part II Programming in World of Warcraft
else
BagBuddy.status:SetText(“Found “ .. #sortTbl .. “ items“)
end
The code displays a different message depending on whether there is more
than one page of items to display. If so, you create a temporary variable that
is set to the smaller of either the max item being displayed, or the length of
the sortTbl table. Because your message looks like “Showing items 49 - 56
of 56“, you need this information to accurately display the last item being
shown.
Final Changes to Support Navigation
You need to make two more changes to support navigation. The first is
initializing BagBuddy to start on page 1. You can do this by adding the
following to the end of the BagBuddy_OnLoad function:
-- Initialize to show the first page
self.page = 1
Secondly, you need to alter the filter buttons to set the page back to 1 every
time a filter is clicked. This is to ensure that you don’t get stuck on page 2 when
there are less than 24 items to display. Change BagBuddy_Filter_OnClick to
the following (changed lines are highlighted):
function BagBuddy_Filter_OnClick(self, button)
BagBuddy.qualityFilter = false
for idx = 0, 5 do
local button = BagBuddy.filters[idx]
if button:GetChecked() then
BagBuddy.qualityFilter = true
end
end
BagBuddy.page = 1
BagBuddy_Update()
end
Adding a Name Filter to BagBuddy
At this point, you have a working inventory addon that allows you to filter
by rarity to better find items. The addon won’t update when your inventory
changes; you learn how to do that in Chapter 13. The next feature you are
going to add is the ability to filter your inventory by name. To accomplish this,
you use an EditBox, a widget that is quite unlike the Button type you’ve been
using so far this chapter.
Chapter 12 Interacting with Widgets 225
Creating an EditBox
The most prevalent edit box in the default user interface is the one that appears
when you press Enter: the chat edit box. Using it you can input commands,
type messages to friends, or even run Lua code. The edit box you use for
BagBuddy won’t have all of these features because all it needs to do is accept
text from the user.
You must exercise caution when working with an EditBox,whetheryouare
creating it in Lua or XML. It has an odd property that causes it to automatically
take the keyboard’s focus when it is displayed and doesn’t (by default) have a
way to relinquish this control. As a result, if you don’t pay attention you could
wind up needing to restart your client to regain control of the keyboard.
You can, however, set a property (via an XML attribute or Lua) and a frame
script to provide better behavior. Open BagBuddy.xml and add the following
definition before the </Frames> tag in the BagBuddy definition, but after the
code for the previous and next buttons:
<EditBox name=“$parent_Input“ parentKey=“input“ autoFocus=“false“>
<Size x=“400“ y=“20“/>
<Anchors>
<Anchor point=“BOTTOMLEFT“>
<Offset x=“32“ y=“100“/>
</Anchor>
</Anchors>
<Scripts>
<OnEscapePressed>
self:ClearFocus()
</OnEscapePressed>
<OnTextChanged>
BagBuddy_Update()
</OnTextChanged>
</Scripts>
<FontString inherits=“GameFontHighlight“/>
</EditBox>
The important part of this code is the autoFocus attribute being set to false.
This ensures that the edit box won’t automatically try to steal the keyboard
whenever it is shown. It’s not enough, however, to ensure that there is an
easy way to get the keyboard’s focus away from the EditBox.Forthisyouset
an OnEscapePressed script. This script handler fires anytime the edit box has
focus and the player presses the escape key. Because most people are used
to pressing escape to clear the focus from an input box, whether it be on the
Web or in World of Warcraft, it’s a good behavior to emulate. The handler
body simply calls the self:ClearFocus() method. This method is specific to
the EditBox type, and simply releases control of the keyboard so it can be used
elsewhere.
226 Part II Programming in World of Warcraft
TIP If you happen to get stuck inside an EditBox there are a few things you can
do to escape, all involving getting the chat frame edit box open:
Right-click your target frame or a party member’s frame. Select the
Whisper option, which should open the chat frame’s edit box.
Click someone’s name in your chat frame and select the Whisper
option, which should open the chat frame’s edit box.
Once you’ve got a place where you can run code, you can reload your user
interface, attach new scripts, or do something else that will stop the runaway
edit box.
You may have noticed what appears to be a dangling FontString ele-
ment at the end of the EditBox definition. Because an EditBox is always
displaying text in some fashion, you need to indicate the font that should be
used to accomplish this. In Lua you can set this using the :SetFont() and
:SetFontObject() methods, but in XML you can just include it as shown in
the preceding code.
The last thing you may have noticed is the OnTextChanged script handler.
This handler is passed a single argument, the edit box itself. You can extract
the text from the edit box using the GetText() method. Your handler simply
calls BagBaddy’s update function to handle any further work.
Filtering by Name
Now you have an edit box that the users can type in, but you need to actually
do something with the text they type. For this, you’ll need to make some minor
changes to the BagBuddy_Update function. Right before the scan loop begins in
that function, add the following:
local nameFilter = BagBuddy.input:GetText():lower()
This code just calls the GetText() method on the input box to retrieve the
text and then converts it to lowercase. You’ll do the same with the item name
when you actually compare it to the user input, so it works properly even if
the user types capital letters.
Now you add a check during the search loop that actually performs the
check to see if the item’s name matches the user input. Add the following code
after the block that checks the item against the quality filters:
if #nameFilter > 0 then
local lowerName = GetItemInfo(link):lower()
shown = shown and string.find(lowerName, nameFilter, 1, true)
end
Chapter 12 Interacting with Widgets 227
This is all you need to add to make filtering work properly. First you check
to see if the text in the edit box is non-empty (that is, if the length of the string
is more than 0). If so, you take the name of the item and make it lowercase and
compare it to the name filter. As a result, only those items that match the name
filter (if it is set) will make it into the item list. Figure 12-6 shows BagBuddy
filtering to show only items whose names contain the word ‘‘potion.’’
Figure 12-6: BagBuddy filtering by item name
Exploring Widget Types
In this chapter you have worked with the normal Frame type, in addition
to Button and EditBox. Quite a number of different widget types exist, all
distinguished by the type of script handlers and methods that are available.
This section details actual examples of the different types of frames to show
how they are typically used. Full details about each of these types is available
in Chapter 29, ‘‘Widget Reference.’’
When exploring these widget types, it’s often useful to look at an existing
example to see how they are used, and what other attributes and elements
might exist in the XML definition.
Button
Buttons are used to allow user input by clicking a meaningful icon or visual
button with text. Buttons can react to clicks and, in some cases, even cast spells
and target units. Examples of buttons include the configuration buttons on the
228 Part II Programming in World of Warcraft
main menu, and the buttons on the player’s action bars (shown in Figure 12-7).
Buttons often show different textures when the mouse is moved over them,
or when they are pressed or disabled. Most buttons display text or icons to
convey more meaning.
Figure 12-7: Main menu buttons (left) and action bar buttons (right)
CheckButton
A CheckButton is a special kind of button that have only two states: checked
and unchecked. They are used to convey toggleable options, and normally
come with text labels to explain which options the checkbox alters. Check
buttons are used primarily in custom configuration interfaces and the user
interface options screen, as shown in Figure 12-8.
Figure 12-8: Checkboxes in the interface options screen
ColorSelect
The ColorSelect frame type (see Figure 12-9) is used by the chat interface
to change output color for channels, along with the background of the chat
windows. It pops up as a dialog box that enables you to select a color (possibly
with alpha transparency) to use for a specific option.
Figure 12-9: ColorSelect example frame as a dialog box
Chapter 12 Interacting with Widgets 229
This widget type doesn’t define any new scripts, but has a number of
methods that allow you to set and get the value of the color wheel and other
color selection elements.
EditBox
The EditBox type of frame is used to allow for text input, along with basic
history and editing capabilities. The simplest example of an edit box is attached
to the chat frame, enabling you to run commands and communicate with other
players, as shown in Figure 12-10.
Figure 12-10: Chat frame’s EditBox
GameTooltip
A GameTooltip is a frame that can display two columns of data that further
describe the UI element you currently have your mouse over, including
buttons, items, and even players in the 3-D world. Figure 12-11 shows an item
tooltip.
Figure 12-11: Item tooltip
MessageFrame
MessageFrames are used by the game to send a stream of errors, warnings, or
messages to the user. This is most often seen with the UIErrorsFrame,which
displays any issues with spellcasting, as shown in Figure 12-12.
Figure 12-12: UIErrorsFrame showing spellcasting errors
Minimap
The Minimap frame type is special in that there can only ever be one of
them. The minimap in the default user interface is used for navigation (see
230 Part II Programming in World of Warcraft
Figure 12-13) and is normally the only one that exists. The portion of the
minimap that is rendered using this widget type is only the map-specific part
of the image, whereas the rest of the elements are attached graphics, buttons,
and fontstrings.
Figure 12-13: Minimap used for navigation
Model
Models are used to display three-dimensional models in-game, potentially
with the capability to pan and zoom in on the model. Models are used in the
default UI within the character window, dressing room at the auction house,
and the tabard planner in the major cities. Figure 12-14 shows the tabard
vendor window, using models.
Figure 12-14: Tabard vendor showing player model
Chapter 12 Interacting with Widgets 231
ScrollingMessageFrame
Being a Massively Multi-player Online Role-Playing Game, WoW has a fair
amount of communication between its players, and these are typically dis-
played in scroll message frames, namely the ChatFrame, shown in Figure 12-15.
Figure 12-15: ChatFrame showing chat messages
ScrollFrame
When something is too large to be displayed in its native window, a scroll frame
can be included to allow the user to scroll either vertically or horizontally. The
ScrollFrame widget type is frequently used throughout the user interface,
particularly within the friends window, the skills window, the auction house,
and the quest log (see Figure 12-16).
Figure 12-16: Scroll frame used in the quest log
SimpleHTML
For presenting data, scrolling message frames aren’t always suitable, such as
when reading a book or item in-game. In these situations, a special type of
frame is used that allows for basic HTML-like markup. When combined with
232 Part II Programming in World of Warcraft
multiple pages or a scroll frame, data becomes easier to present. Figure 12-17
shows a plaque in Stormwind, which uses a SimpleHTML frame.
Figure 12-17: SimpleHTML frame displaying a plaque
Slider
Sliders are used when there is a range of numbers that can possibly be
selected. They’re used primarily in the default user interface options screen
(see Figure 12-18). Sliders enable the developer to set a minimum value, a
maximum value, and the default step that the slider will allow, so you can
control precision.
Figure 12-18: Sliders in the default interface options
StatusBar
StatusBars are used throughout the default user interface to show progress or
percentages, such as in the skills window (see Figure 12-19). To use a status
bar, you must supply a texture to be shown, as well as minimum/maximum
Chapter 12 Interacting with Widgets 233
values for the bar. Then you can simply set the value of the bar to show the
correct value.
Figure 12-19: StatusBars displayed in the skills window
Summary
This chapter introduced you to two different types of interactive widgets that
can be used in custom addons. You created multiple buttons that showed
tooltips when the mouse moved over them, and buttons that could be clicked
to accomplish some task. In addition, you utilized an edit box to accept input
from the user.
The Code
BagBuddy.lua
function BagBuddy_OnLoad(self)
SetPortraitToTexture(self.portrait, i
“Interface\\Icons\\INV_Misc_EngGizmos_30“)
-- Create the item slots
self.items = {}
for idx = 1, 24 do
local item = CreateFrame(“Button“, “BagBuddy_Item“ .. idx, i
self, “BagBuddyItemTemplate“)
self.items[idx] = item
if idx == 1 then
item:SetPoint(“TOPLEFT“, 40, -73)
elseif idx == 7 or idx == 13 or idx == 19 then
item:SetPoint(“TOPLEFT“, self.items[idx-6], “BOTTOMLEFT“, i
0, -7)
else
item:SetPoint(“TOPLEFT“, self.items[idx-1], “TOPRIGHT“, i
12, 0)
end
end
-- Create the filter buttons
self.filters = {}
234 Part II Programming in World of Warcraft
for idx=0,5 do
local button = CreateFrame(“CheckButton“, i
“BagBuddy_Filter“ .. idx, self, “BagBuddyFilterTemplate“)
SetItemButtonTexture(button, i
“Interface\\ICONS\\INV_Misc_Gem_Pearl_03“)
self.filters[idx] = button
if idx == 0 then
button:SetPoint(“BOTTOMLEFT“, 40, 200)
else
button:SetPoint(“TOPLEFT“, self.filters[idx-1], i
“TOPRIGHT“, 12, 0)
end
button.icon:SetVertexColor(GetItemQualityColor(idx))
button:SetChecked(false)
button.quality = idx
button.glow:Hide()
end
self.filters[-1] = self.filters[0]
-- Initialize to show the first page
self.page = 1
end
local function itemNameSort(a, b)
return a.name < b.name
end
function BagBuddy_Update()
local items = {}
local nameFilter = BagBuddy.input:GetText():lower()
-- Scan through the bag slots, looking for items
for bag = 0, NUM_BAG_SLOTS do
for slot = 0, GetContainerNumSlots(bag) do
local texture, count, locked, quality, readable, i
lootable, link = GetContainerItemInfo(bag, slot)
if texture then
local shown = true
if BagBuddy.qualityFilter then
shown = shown and BagBuddy.filters[quality]:GetChecked()
end
if #nameFilter > 0 then
local lowerName = GetItemInfo(link):lower()
shown = shown and string.find(lowerName, nameFilter, i
Chapter 12 Interacting with Widgets 235
1, true)
end
if shown then
-- If an item is found, grab the item number and i
store other data
local itemNum = tonumber(link:match(“|Hitem:(%d+):“))
if not items[itemNum] then
items[itemNum] = {
texture = texture,
count = count,
quality = quality,
name = GetItemInfo(link),
link = link,
}
else
-- The item already exists in our table, just i
update the count
items[itemNum].count = items[itemNum].count + count
end
end
end
end
end
local sortTbl = {}
for link, entry in pairs(items) do
table.insert(sortTbl, entry)
end
table.sort(sortTbl, itemNameSort)
-- Now update the BagBuddyFrame with the listed items (in order)
local max = BagBuddy.page * 24
local min = max - 23
for idx = min, max do
local button = BagBuddy.items[idx - min + 1]
local entry = sortTbl[idx]
if entry then
-- There is an item in this slot
button.link = entry.link
button.icon:SetTexture(entry.texture)
if entry.count > 1 then
button.count:SetText(entry.count)
button.count:Show()
else
button.count:Hide()
236 Part II Programming in World of Warcraft
end
if entry.quality > 1 then
button.glow:SetVertexColor(i
GetItemQualityColor(entry.quality))
button.glow:Show()
else
button.glow:Hide()
end
button:Show()
else
button.link = nil
button:Hide()
end
end
-- Update page buttons
if min > 1 then
BagBuddy.prev:Enable()
else
BagBuddy.prev:Disable()
end
if max < #sortTbl then
BagBuddy.next:Enable()
else
BagBuddy.next:Disable()
end
-- Update the status text
if #sortTbl > 24 then
local max = math.min(max, #sortTbl)
local msg = string.format(“Showing items %d - %d of %d“, i
min, max, #sortTbl)
BagBuddy.status:SetText(msg)
else
BagBuddy.status:SetText(“Found “ .. #sortTbl .. “ items“)
end
end
function BagBuddy_Button_OnEnter(self, motion)
if self.link then
GameTooltip:SetOwner(self, “ANCHOR_TOPRIGHT“)
GameTooltip:SetHyperlink(self.link)
GameTooltip:Show()
end
end
function BagBuddy_Button_OnLeave(self, motion)
GameTooltip:Hide()
Chapter 12 Interacting with Widgets 237
end
function BagBuddy_Filter_OnEnter(self, motion)
GameTooltip:SetOwner(self, “ANCHOR_TOPRIGHT“)
GameTooltip:SetText(_G[“ITEM_QUALITY“ .. i
self.quality .. “_DESC“])
GameTooltip:Show()
end
function BagBuddy_Filter_OnLeave(self, motion)
GameTooltip:Hide()
end
function BagBuddy_Filter_OnClick(self, button)
BagBuddy.qualityFilter = false
for idx = 0, 5 do
local button = BagBuddy.filters[idx]
if button:GetChecked() then
BagBuddy.qualityFilter = true
end
end
BagBuddy.page = 1
BagBuddy_Update()
end
function BagBuddy_NextPage(self)
BagBuddy.page = BagBuddy.page + 1
BagBuddy_Update(BagBuddy)
end
function BagBuddy_PrevPage(self)
BagBuddy.page = BagBuddy.page - 1
BagBuddy_Update(BagBuddy)
end
BagBuddy.xml
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Button name=“BagBuddyItemTemplate“ virtual=“true“>
<Size>
<AbsDimension x=“37“ y=“37“/>
</Size>
<Layers>
<Layer level=“BORDER“>
<Texture name=“$parentIconTexture“ parentKey=“icon“/>
<FontString name=“$parentCount“ parentKey=“count“i
238 Part II Programming in World of Warcraft
inherits=“NumberFontNormal“ justifyH=“RIGHT“ hidden=“true“>
<Anchors>
<Anchor point=“BOTTOMRIGHT“>
<Offset>
<AbsDimension x=“-5“ y=“2“/>
</Offset>
</Anchor>
</Anchors>
</FontString>
</Layer>
<Layer level=“OVERLAY“>
<Texture name=“$parentGlow“ parentKey=“glow“ i
alphaMode=“ADD“ file=“Interface\Buttons\UI-ActionButton-Border“>
<Size x=“70“ y=“70“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Color r=“1.0“ g=“1.0“ b=“1.0“ a=“0.6“/>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnEnter function=“BagBuddy_Button_OnEnter“/>
<OnLeave function=“BagBuddy_Button_OnLeave“/>
</Scripts>
<NormalTexture name=“$parentNormalTexture“ i
file=“Interface\Buttons\UI-Quickslot2“>
<Size>
<AbsDimension x=“64“ y=“64“/>
</Size>
<Anchors>
<Anchor point=“CENTER“>
<Offset>
<AbsDimension x=“0“ y=“-1“/>
</Offset>
</Anchor>
</Anchors>
</NormalTexture>
<PushedTexture file=“Interface\Buttons\UI-Quickslot-Depress“/>
<HighlightTexture i
file=“Interface\Buttons\ButtonHilight-Square“ alphaMode=“ADD“/>
</Button>
<CheckButton name=“BagBuddyFilterTemplate“ i
inherits=“BagBuddyItemTemplate“ virtual=“true“>
<Scripts>
<OnEnter function=“BagBuddy_Filter_OnEnter“/>
<OnLeave function=“BagBuddy_Filter_OnLeave“/>
<OnClick function=“BagBuddy_Filter_OnClick“/>
</Scripts>
Chapter 12 Interacting with Widgets 239
<CheckedTexture file=“Interface\Buttons\CheckButtonHilight“ i
alphaMode=“ADD“/>
</CheckButton>
<Frame name=“BagBuddy“ parent=“UIParent“>
<Size x=“384“ y=“512“/>
<Anchors>
<Anchor point=“CENTER“ relativePoint=“CENTER“ i
relativeTo=“UIParent“/>
</Anchors>
<Layers>
<Layer level=“BACKGROUND“>
<Texture name=“$parent_Portrait“ parentKey=“portrait“ i
file=“Interface\Icons\INV_Misc_EngGizmos_30“>
<Size x=“60“ y=“60“/>
<Anchors>
<Anchor point=“TOPLEFT“>
<Offset x=“7“ y=“-6“/>
</Anchor>
</Anchors>
</Texture>
</Layer>
<Layer level=“OVERLAY“>
<FontString name=“$parent_Title“ parentKey=“title“ i
inherits=“GameFontNormal“ text=“BagBuggy“>
<Anchors>
<Anchor point=“TOP“>
<Offset x=“0“ y=“-18“/>
</Anchor>
</Anchors>
</FontString>
<FontString name=“$parent_Status“ parentKey=“status“ i
inherits=“GameFontHighlight“>
<Anchors>
<Anchor point=“CENTER“ relativePoint=“BOTTOM“>
<Offset x=“-10“ y=“150“/>
</Anchor>
</Anchors>
</FontString>
</Layer>
<Layer level=“BORDER“>
<Texture file=“Interface\BankFrame\UI-BankFrame-TopLeft“>
<Anchors>
<Anchor point=“TOPLEFT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-TopRight“>
<Anchors>
<Anchor point=“TOPRIGHT“/>
240 Part II Programming in World of Warcraft
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-BotLeft“>
<Anchors>
<Anchor point=“BOTTOMLEFT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-BotRight“>
<Anchors>
<Anchor point=“BOTTOMRIGHT“/>
</Anchors>
</Texture>
</Layer>
</Layers>
<Frames>
<Button name=“$parent_Close“ parentKey=“close“ i
inherits=“UIPanelCloseButton“>
<Anchors>
<Anchor point=“TOPRIGHT“>
<Offset x=“-30“ y=“-8“/>
</Anchor>
</Anchors>
</Button>
<Button name=“BagBuddy_PrevButton“ parentKey=“prev“>
<Size x=“32“ y=“32“/>
<Anchors>
<Anchor point=“CENTER“ relativeTo=“BagBuddy“ i
relativePoint=“BOTTOMLEFT“>
<Offset>
<AbsDimension x=“50“ y=“150“/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick function=“BagBuddy_PrevPage“/>
</Scripts>
<NormalTexture i
file=“Interface\Buttons\UI-SpellbookIcon-PrevPage-Up“/>
<PushedTexture i
file=“Interface\Buttons\UI-SpellbookIcon-PrevPage-Down“/>
<DisabledTexture i
file=“Interface\Buttons\UI-SpellbookIcon-PrevPage-Disabled“/>
<HighlightTexture i
file=“Interface\Buttons\UI-Common-MouseHilight“ alphaMode=“ADD“/>
</Button>
<Button name=“BagBuddy_NextButton“ parentKey=“next“>
<Size x=“32“ y=“32“/>
<Anchors>
<Anchor point=“CENTER“ relativeTo=“BagBuddy“ i
Chapter 12 Interacting with Widgets 241
relativePoint=“BOTTOMRIGHT“>
<Offset>
<AbsDimension x=“-70“ y=“150“/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick function=“BagBuddy_NextPage“/>
</Scripts>
<NormalTexture i
file=“Interface\Buttons\UI-SpellbookIcon-NextPage-Up“/>
<PushedTexture i
file=“Interface\Buttons\UI-SpellbookIcon-NextPage-Down“/>
<DisabledTexture i
file=“Interface\Buttons\UI-SpellbookIcon-NextPage-Disabled“/>
<HighlightTexture i
file=“Interface\Buttons\UI-Common-MouseHilight“ alphaMode=“ADD“/>
</Button>
<EditBox name=“$parent_Input“ parentKey=“input“ i
autoFocus=“false“>
<Size x=“400“ y=“20“/>
<Anchors>
<Anchor point=“BOTTOMLEFT“>
<Offset x=“32“ y=“100“/>
</Anchor>
</Anchors>
<Scripts>
<OnEscapePressed>
self:ClearFocus()
</OnEscapePressed>
<OnTextChanged>
BagBuddy_Update()
</OnTextChanged>
</Scripts>
<FontString inherits=“GameFontHighlight“/>
</EditBox>
</Frames>
<Scripts>
<OnLoad function=“BagBuddy_OnLoad“/>
</Scripts>
</Frame>
</Ui>
CHAPTER
13
Responding to Game Events
By this point you should be fairly comfortable making new frames, textures,
and font strings. You’ve defined several templates for use in your own
addons, explored Blizzard’s own FrameXML templates, and learned how
to make your widgets more interactive by responding to widget scripts
and user input. This chapter introduces the next aspect of user interface
programming: responding to changes in the game client using the event
system and event-based programming.
Understanding Events
Events are a way for the game client to notify addons of a change in the state
of the game. For example, when the player’s health changes, the user interface
needs to be informed so it can update the status bar. If it weren’t for events, the
game client would need to continuously update the health bar, which would
be very wasteful.
Events range from the extremely detailed to simple notifications that some-
thing has changed. A good example of the former is the UNIT_COMBAT event.
This event is used for the combat notifications that appear on the player frame.
It fires whenever a unit takes damage, is healed, or performs some other
combat action (such as dodging, missing, or parrying). When the event is
finally triggered, it provides the following information:
The unit that was affected
The action type that occurred (wound, dodge, heal, and so on)
243
244 Part II Programming in World of Warcraft
A modifier to the action, such as crushing or critical
The amount of damage or healing that was received
A number indicating the type of damage that was dealt
Registering for Events
To do anything meaningful with game events, you must first register for them.
Like many other things in the user interface, you do this through frames. Every
frame object has a RegisterEvent()method for this purpose. It expects a single
string argument, the name of the event. Run the following code in-game to
create a new frame, and register for the UNIT_COMBAT event:
MyEventFrame = CreateFrame(“Frame“, “MyEventFrame“, UIParent)
MyEventFrame:RegisterEvent(“UNIT_COMBAT“)
You cannot register for more than one event at a time, but you can simply
call RegisterEvent() multiple times, or write a helper function that can do
multiple registrations for you.
Once a frame has been registered for an event, it will continue to receive
event information until the event has been unregistered. The Unregister
Event() event is provided for this purpose, taking the same argument as
RegisterEvent().
Responding to Events with OnEvent
To actually respond to events, you must set an OnEvent widget script for the
frame that has registered for events. Each widget script can have at most one
handler, so you will likely register for multiple events on the same frame, and
your handler must be capable of differentiating between different events. This
is done by examining the arguments that are passed to your handler:
selfThe frame that registered for the event
eventThe event that is being triggered
...A list of additional arguments to the event
Because the handler is given the name of the event as well as the frame itself,
you can use basic conditional statements to differentiate between different
events. For example, if you register for both UNIT_HEALTH and UNIT_MANA and
need to distinguish between them, you could do the following:
if event == “UNIT_HEALTH“ then
-- do something with the unit health
elseif event == “UNIT_MANA“ then
Chapter 13 Responding to Game Events 245
-- do something different with mana
end
Add an OnEvent script to the MyEventFrame you created previously. Run the
following code in-game:
function MyEventFrame_OnEvent(self, event, ...)
print(“Event handler“, event, ...)
end
MyEventFrame:SetScript(“OnEvent“, MyEventFrame_OnEvent)
Alternatively, you could just create the new function inline:
MyEventFrame:SetScript(“OnEvent“, function(self, event, ...)
print(“Event handler“, event, ...)
end)
An even shorter form (that doesn’t allow you to add a custom message to
the start) simply sets the print function as the script handler:
MyEventFrame:SetScript(“OnEvent“, print)
The result of any of these will be a message sent to the chat frame each time
the event occurs. You can test this by fighting with something in-game. You
should receive messages for both you and your enemy. Figure 13-1 shows
some messages from combat.
Figure 13-1: Event messages for UNIT_COMBAT
In this case you can see that the event has five arguments that are passed to
the handler. You’ll work with the UNIT_COMBAT event more in Chapter 14 and
learn what each of these arguments are.
This simple method of setting up event handlers to print debug information
can be useful when working on an addon because it lets you see easily which
arguments were sent with a given event. Alternatively, you could use the new
/eventtrace command that was added to WoW in 3.2. It is discussed at the
end of this chapter.
246 Part II Programming in World of Warcraft
Query Events
There are certain API calls that require communication with the server, instead
of getting their information locally from the game client. For example, when
you want to update your guild roster, you call the GuildRoster() function. You
might expect the information to be available immediately, but the information
is all stored on the server so you must wait for the GUILD_ROSTER_UPDATE event,
which signifies that the data has been received by the client and is available.
When working with an API system, always read the related documentation
so you will understand how the information becomes available.
Tracking Changes to Inventory for BagBuddy
The event-based system used in World of Warcraft is conceptually simple,
but in practice it can be a bit tricky to work this. In this section, you’ll use
the BAG_UPDATE event to add some functionality to BagBuddy. To sort the
inventory with the most recently looted items first, you must monitor changes
to the player’s inventory. The BAG_UPDATE event fires whenever something
changes in the player’s bags, so it gives you just what you need.
Examining the BAG_UPDATE Event
BAG_UPDATE is a very interesting event because it can fire for a number of
reasons, and doesn’t really provide much information. In fact, there is only
one argument to the event: the numeric index of the bag that was updated.
The event fires whenever the state of the player’s containers changes, such as
when the player moves items from one bag to another, or loots a new item.
If you write a simple addon to monitor the event, you might see that it
can fire multiple times back to back. For example, if you loot two items and
one of them goes into an existing stack, and the other goes into a new slot
elsewhere in your inventory, the event then fires for each of the bags that
changed. In addition, the BAG_UPDATE event’s first argument is sometimes a
negative number due to the internal implementation of the player’s inventory
and equipment. As a result, you’ll need to ignore any negative values, and run
your handler only when a legitimate bag has been updated.
Tracking New Inventory Items
For the purposes of BagBuddy, you just want to watch to see new items enter
the inventory so you can somehow tag them with the time they were looted.
Then when you go through the display loop in BagBuddy_Update, you can sort
according to that value.
Chapter 13 Responding to Game Events 247
You’ll need a place to store the item counts for each bag, so add the following
to the end of BagBuddy_OnLoad in BagBuddy.lua:
self.bagCounts = {}
Now add the following function definition somewhere in BagBuddy.lua:
function BagBuddy_ScanBag(bag, initial)
if not BagBuddy.bagCounts[bag] then
BagBuddy.bagCounts[bag] = {}
end
local itemCounts = {}
for slot = 0, GetContainerNumSlots(bag) do
local texture, count, locked, quality, readable, lootable, link = i
GetContainerItemInfo(bag, slot)
if texture then
local itemId = tonumber(link:match(“|Hitem:(%d+):“))
if not itemCounts[itemId] then
itemCounts[itemId] = count
else
itemCounts[itemId] = itemCounts[itemId] + count
end
end
end
if initial then
for itemId, count in pairs(itemCounts) do
BagBuddy_ItemTimes[itemId] = BagBuddy_ItemTimes[itemId] or time()
end
else
for itemId, count in pairs(itemCounts) do
local oldCount = BagBuddy.bagCounts[bag][itemId] or 0
if count > oldCount then
BagBuddy_ItemTimes[itemId] = time()
end
end
end
BagBuddy.bagCounts[bag] = itemCounts
end
This function takes a numerical bag index, and a flag called initial.The
flag will indicate whether the function is being called on the first scan of a
session because there would be no prior count with which to compare.
Next, the function loops over all of the slots in the given bag and checks to
see if there is an item in the slot. If so, it parses the item ID from the hyperlink
and updates the local itemCounts table with the new count.
248 Part II Programming in World of Warcraft
Item times are stored in the global BagBuddy_ItemTimes tables, which we
will create in a later section. When the initial flag is set, the item times are
set using the prior value, if possible, or the current time. At any other time, the
item counts are compared to the previous item counts. If the count has gone
up, then the item time is set to the current time. Finally, the new itemCounts
table is stored in BagBuddy.bagCounts so it can be used on the next inventory
change.
Note that you’re using the item number here to store the loot time, otherwise
items with different unique IDs would show up as distinct items. Ideally you
would use the item string (excluding the unique ID portion) so you can
differentiate between items that have different enchants or sockets. This
version just lumps those types of items into a single stack for simplicity.
Writing a New Sorting Function
The previous version of this addon sorted items by name, but now you want
to include item loot time as part of the sorting. Insert a new sorting function
by adding the following definition before BagBuddy_Update():
local function itemTimeNameSort(a, b)
-- If the two items were looted at the same time
local aTime = BagBuddy.itemTimes[a.num]
local bTime = BagBuddy.itemTimes[b.num]
if aTime == bTime then
return a.name < b.name
else
return aTime >= bTime
end
end
The function checks to see if the loot times are the same, in which case it
sorts the items by name. If the times are different, then they are sorted in
descending order (by using >= instead of <) in the comparison. To use this new
sorting function, you need to make some small changes to the update.
Altering BagBuddy_Update
The changes to BagBuddy_Update are very simple; you just need to add the item
number to the entry table and call the new sort function. In BagBuddy_Update,
the new item table code should be changed to the following (changed line is
highlighted):
if not items[itemNum] then
items[itemNum] = {
texture = texture,
Chapter 13 Responding to Game Events 249
count = count,
quality = quality,
name = GetItemInfo(link),
link = link,
num = itemNum,
}
else
Finally, change the call to table.sort from
table.sort(sortTbl, itemNameSort)
to
table.sort(sortTbl, itemTimeNameSort)
Adding an OnEvent Handler
To actually catch the BAG_UPDATE events, you need to add an event handler.
Open BagBuddy.xml and add the following to the <Scripts> element in the
definition of the BagBuddy frame:
<OnEvent function=“BagBuddy_OnEvent“/>
Now open BagBuddy.lua and add this function definition somewhere
toward the end of the file:
function BagBuddy_OnEvent(self, event, ...)
if event == “ADDON_LOADED“ and ... == “BagBuddy“ then
if not BagBuddy_ItemTimes then
BagBuddy_ItemTimes = {}
end
for bag = 0, NUM_BAG_SLOTS do
-- Use the optional flag to skip updating times
BagBuddy_ScanBag(bag, true)
end
self:UnregisterEvent(“ADDON_LOADED“)
self:RegisterEvent(“BAG_UPDATE“)
elseif event == “BAG_UPDATE“ then
local bag = ...
if bag >= 0 then
BagBuddy_ScanBag(bag)
if BagBuddy:IsVisible() then
BagBuddy_Update()
end
end
end
end
250 Part II Programming in World of Warcraft
This handler is set to watch for two events: ADDON_LOADED and BAG_UPDATE.
ADDON_LOADED is used as an initialization event because it indicates that an
addon is fully loaded. However, addons can sometimes load out of order
due to dependencies and other API calls, so you have to check the first
argument to the function to see which addon has finished loading.
When BagBuddy’s ADDON_LOADED event is encountered, the BagBuddy_
ItemTimes table is created and the initial scan is run for each of the player’s
bags. After that, the addon no longer cares about the ADDON_LOADED event, so
it un-registers it. Finally, the handler registers for the BAG_UPDATE event, so it
can detect changes to the player’s inventory.
The BAG_UPDATE portion of the handler is very simple; it just checks to see
if the bag index is greater than or equal to 0(the player’s backpack) and then
runs the bag scan. If the frame is visible, it calls BagBuddy_Update() to update
the frame. This ensures that the frame is always showing the latest information.
Finally, you need to register for the ADDON_LOADED event, so add the following
to the end of BagBuddy_OnLoad():
self:RegisterEvent(“ADDON_LOADED“)
Now when you log into the game and loot some items, you should then see
them sorted with the most recently looted items shown first. In addition you
can still filter the items by rarity or name and have them sorted by loot time.
Cleaning Up
Right now the frame is visible when the game is loaded, and can’t easily be
re-opened once it’s been closed. In addition, it would be nice if the frame
would operate like the rest of the panels in the user interface. Luckily there’s
an easy system that allows you to do that.
At the top of BagBuddy_OnLoad() add the following code:
UIPanelWindows[“BagBuddy“] = {
area = “left“,
pushable = 1,
whileDead = 1,
}
UIPanelWindows is a special global table that contains definitions of the
various panels that are controlled by the user interface. The key is the name
of the frame and the value is a table of options. In this case, you indicate
that the window should appear on the left side of the screen, can be pushed
toward the center by another panel, and should be visible while the player
is dead. Additionally, by adding your frame to the UIPanelWindows table, it
Chapter 13 Responding to Game Events 251
automatically gains the capability to be closed by pressing the Escape key
rather than having to click the close button.
Unfortunately, by the time the BagBuddy_OnLoad() function is run, the
frame will already have been shown, so it won’t be treated as one of the spe-
cial UI panels. Additionally, it doesn’t seem to make much sense to have
the frame shown every time the player logs in. Open BagBuddy.xml and
change the opening tag for BagBuddy to the following (the addition has been
highlighted):
<Frame name=“BagBuddy“ parent=“UIParent“ hidden=“true“>
Now when you’d like to see the frame, you can run the following command
and BagBuddy will behave the same as the other UI panels:
/run ShowUIPanel(BagBuddy)
Adding a Slash Command
You can make it easier to open BagBuddy by adding the following slash
command definition to the end of BagBuddy.lua:
SLASH_BAGBUDDY1 = “/bb“
SLASH_BAGBUDDY2 = “/bagbuddy“
SlashCmdList[“BAGBUDDY“] = function(msg, editbox)
BagBuddy.input:SetText(msg)
ShowUIPanel(BagBuddy)
end
This provides two new slash commands (/bb and /bagbuddy) that both work
in the same way. Any text typed after the slash command will be put into the
edit box and used as a name filter, then the panel is shown. Now instead of
running a script command, you can just type /bb to open the frame.
Slash commands are further discussed in Chapter 17.
Storing Data with SavedVariables
With this version of BagBuddy, the item times are reset every time the user
interface is reloaded. If you reload your user interface in the middle of a
questing session and then open BagBuddy, you will find that the items are
again sorted by name rather than by loot time, making that feature a bit
less useful. To fix this, you need some way to carry data from session to
session.
252 Part II Programming in World of Warcraft
World of Warcraft offers a system that allows addons to register certain
global variables to be saved between game sessions. These are called saved
variables, named after the table of contents directive that is used to specify
them. There are two different types of saved variables:
SavedVariablesAccount-wide, accessible to any character on a given
account.
SavedVariablesPerCharacterSeparate for each individual character,
so not even two characters on the same server can share them.
Although you could obviously take a normal saved variable and partition
it so multiple users can use it without interfering with each other’s data,
each character truly has access to all of the data. On the other hand, there
is no way to simulate a normal saved variable with a per-character saved
variable because all saving and loading is handled directly by the game
client.
Registering a New Saved Variable
Using saved variables is quite easy; you just need to add a directive to your
addon’s table of contents file, and restart the game client. When the game
client is loaded, it loads any stored data and makes it available to your addon
(more on this later). When the game client is closed, a character logs out, or
the user interface is reloaded, the data is saved out to disk.
Start by adding a saved variable to BagBuddy.toc. Open the file and add the
following after the ## Notes directive:
## SavedVariablesPerCharacter: BagBuddy_ItemTimes
There’s really no reason that users would need access to each other’s times,
so you can declare your saved variable to be per-character only. That way you
don’t have to be concerned about storing your data in any specific place;
you can just leave it in the table itself.
For this change to take effect, you will need to quit your client and re-open
it. Changes that are made to the metadata of an addon’s table of contents file
are refreshed only when the client is opened, not on user interface reload.
Saved Variables and ADDON_LOADED
When an addon is being loaded (that is, when the code is actually being parsed
and run) any saved variables are not yet available. Once the addon has finished
initializing, the client loads the saved variables and fires the ADDON_LOADED
Chapter 13 Responding to Game Events 253
event. Although the reasons for this weren’t discussed in the previous section,
that is why initialization is delayed until ADDON_LOADED.
Using Items from BagBuddy
Finding items in your inventory is great, but it would be nicer to be able to
click to use them once you’ve found them. This can be accomplished using
secure templates, which are discussed in Chapter 15. For now, you can make the
following changes to your code to enable that functionality.
In BagBuddy_OnLoad(), change the loop that creates item slots to register for
right-clicks (change is highlighted):
-- Create the item slots
self.items = {}
for idx = 1, 24 do
local item = CreateFrame(“Button“, “BagBuddy_Item“ .. idx, self, i
“BagBuddyItemTemplate“)
item:RegisterForClicks(“RightButtonUp“)
self.items[idx] = item
if idx == 1 then
item:SetPoint(“TOPLEFT“, 40, -73)
elseif idx == 7 or idx == 13 or idx == 19 then
item:SetPoint(“TOPLEFT“, self.items[idx-6], “BOTTOMLEFT“, 0, -7)
else
item:SetPoint(“TOPLEFT“, self.items[idx-1], “TOPRIGHT“, 12, 0)
end
end
In BagBuddy_Update(), add the following highlighted line in the conditional
that indicates there is an item in the slot. This sets the button up to use the
named item when it is right-clicked.
if entry then
-- There is an item in this slot
button:SetAttribute(“item2“, entry.name)
button.link = entry.link
button.icon:SetTexture(entry.texture)
The last two changes must be made in BagBuddy.xml. First, change the
opening tag for BagBuddyItemTemplate from
<Button name=“BagBuddyItemTemplate“ virtual=“true“>
254 Part II Programming in World of Warcraft
to
<Button name=“BagBuddyItemTemplate“ i
inherits=“SecureActionButtonTemplate“ virtual=“true“>
Finally, add an attribute definition between the </Layers> tag and the
<Scripts> tag for BagBuddyItemTemplate:
<Attributes>
<Attribute name=“type2“ type=“string“ value=“item“/>
</Attributes>
Now when you open BagBuddy, you should be able to use items (such as
food, potions, bandages, and quest items) by right-clicking on them.
Finding the Right Event Using /eventtrace
One of the most challenging aspects of writing an addon for World of Warcraft
is finding the right events to ensure your addon functions properly. Some
applications are very simple, such as using UNIT_HEALTH to monitor the health
of an in-game unit. Others, such as those dealing with the player’s containers
and inventory, can be a bit tricky to deal with at times.
The Blizzard_DebugTools addon included with the default user interface
provides the slash command /eventtrace that makes tracking down event
information a bit easier. The command has a few different forms:
/eventtrace startStart capturing events, whether or not the window
is shown.
/eventtrace stopStop capturing events.
/eventtraceShow the window if it is currently hidden, and start
capturing events if the window hasn’t been shown before. Otherwise,
hide the window.
/eventtrace <num>If the addon is not currently capturing events,
capture exactly <num> events and then stop capturing events.
The results are displayed for you in an easy-to-navigate window, shown in
Figure 13-2.
You can scroll through the resulting events to view their arguments and
the time at which they were called. In addition, the event trace will show you
how much time elapsed between two events (if any) and how many times the
screen was updated.
When you need to find out what events fires under a certain situation (such
as when you cast a spell on an enemy), you can start an event trace and
replicate the situation. Then you can stop the event trace and explore the
events that fired to get the information you need.
Chapter 13 Responding to Game Events 255
Figure 13-2: /eventtrace window showing event information
Summary
This chapter explored how the game client notifies addons of changes to the
state of the game. You added event handling to BagBuddy to track changes to
the player’s inventory. The last few chapters have introduced you to all of the
vital parts of creating an addon. The next chapter pulls everything together to
create another fully-functional addon called CombatTracker.
The Code
BagBuddy.lua
function BagBuddy OnLoad(self)
UIPanelWindows[“BagBuddy“] = {
area = “left“,
pushable = 1,
whileDead = 1,
}
SetPortraitToTexture(self.portrait, i
“Interface\\Icons\\INV Misc EngGizmos 30“)
-- Create the item slots
256 Part II Programming in World of Warcraft
self.items = {}
for idx = 1, 24 do
local item = CreateFrame(“Button“, “BagBuddy Item“ .. idx, i
self, “BagBuddyItemTemplate“)
item:RegisterForClicks(“RightButtonUp“)
self.items[idx] = item
if idx == 1 then
item:SetPoint(“TOPLEFT“, 40, -73)
elseif idx == 7 or idx == 13 or idx == 19 then
item:SetPoint(“TOPLEFT“, self.items[idx-6], “BOTTOMLEFT“, 0, -7)
else
item:SetPoint(“TOPLEFT“, self.items[idx-1], “TOPRIGHT“, 12, 0)
end
end
-- Create the filter buttons
self.filters = {}
for idx=0,5 do
local button = CreateFrame(“CheckButton“,
“BagBuddy Filter“ .. idx, self, “BagBuddyFilterTemplate“)
SetItemButtonTexture(button, i
“Interface\\ICONS\\INV Misc Gem Pearl 03“)
self.filters[idx] = button
if idx == 0 then
button:SetPoint(“BOTTOMLEFT“, 40, 200)
else
button:SetPoint(“TOPLEFT“, self.filters[idx-1], “TOPRIGHT“, 12, 0)
end
button.icon:SetVertexColor(GetItemQualityColor(idx))
button:SetChecked(false)
button.quality = idx
button.glow:Hide()
end
self.filters[-1] = self.filters[0]
-- Initialize to show the first page
self.page = 1
self.bagCounts = {}
self:RegisterEvent(“ADDON LOADED“)
end
local function itemNameSort(a, b)
return a.name < b.name
end
local function itemTimeNameSort(a, b)
Chapter 13 Responding to Game Events 257
-- If the two items were looted at the same time
local aTime = BagBuddy ItemTimes[a.num]
local bTime = BagBuddy ItemTimes[b.num]
if aTime == bTime then
return a.name < b.name
else
return aTime >= bTime
end
end
function BagBuddy Update()
local items = {}
local nameFilter = BagBuddy.input:GetText():lower()
-- Scan through the bag slots, looking for items
for bag = 0, NUM BAG SLOTS do
for slot = 0, GetContainerNumSlots(bag) do
local texture, count, locked, quality, readable, lootable, i
link = GetContainerItemInfo(bag, slot)
if texture then
local shown = true
if BagBuddy.qualityFilter then
shown = shown and BagBuddy.filters[quality]:GetChecked()
end
if #nameFilter > 0 then
local lowerName = GetItemInfo(link):lower()
shown = shown and string.find(lowerName, nameFilter, 1, true)
end
if shown then
-- If an item is found, grab item number and store other data
local itemNum = tonumber(link:match(“|Hitem:(%d+):“))
if not items[itemNum] then
items[itemNum] = {
texture = texture,
count = count,
quality = quality,
name = GetItemInfo(link),
link = link,
num = itemNum,
}
else
-- The item already exists, just update the count
items[itemNum].count = items[itemNum].count + count
end
258 Part II Programming in World of Warcraft
end
end
end
end
local sortTbl = {}
for link, entry in pairs(items) do
table.insert(sortTbl, entry)
end
table.sort(sortTbl, itemTimeNameSort)
-- Now update the BagBuddyFrame with the listed items (in order)
local max = BagBuddy.page * 24
local min = max - 23
for idx = min, max do
local button = BagBuddy.items[idx - min + 1]
local entry = sortTbl[idx]
if entry then
-- There is an item in this slot
button:SetAttribute(“item2“, entry.name)
button.link = entry.link
button.icon:SetTexture(entry.texture)
if entry.count > 1 then
button.count:SetText(entry.count)
button.count:Show()
else
button.count:Hide()
end
if entry.quality > 1 then
button.glow:SetVertexColor(GetItemQualityColor(entry.quality))
button.glow:Show()
else
button.glow:Hide()
end
button:Show()
else
button.link = nil
button:Hide()
end
end
-- Update page buttons
if min > 1 then
BagBuddy.prev:Enable()
else
BagBuddy.prev:Disable()
Chapter 13 Responding to Game Events 259
end
if max < #sortTbl then
BagBuddy.next:Enable()
else
BagBuddy.next:Disable()
end
-- Update the status text
if #sortTbl > 24 then
local max = math.min(max, #sortTbl)
local msg = string.format(“Showing items %d - %d of %d“, min, i
max, #sortTbl)
BagBuddy.status:SetText(msg)
else
BagBuddy.status:SetText(“Found “ .. #sortTbl .. “ items“)
end
end
function BagBuddy Button OnEnter(self, motion)
if self.link then
GameTooltip:SetOwner(self, “ANCHOR TOPRIGHT“)
GameTooltip:SetHyperlink(self.link)
GameTooltip:Show()
end
end
function BagBuddy Button OnLeave(self, motion)
GameTooltip:Hide()
end
function BagBuddy Filter OnEnter(self, motion)
GameTooltip:SetOwner(self, “ANCHOR TOPRIGHT“)
GameTooltip:SetText( G[“ITEM QUALITY“ .. self.quality .. “ DESC“])
GameTooltip:Show()
end
function BagBuddy Filter OnLeave(self, motion)
GameTooltip:Hide()
end
function BagBuddy Filter OnClick(self, button)
BagBuddy.qualityFilter = false
for idx = 0, 5 do
local button = BagBuddy.filters[idx]
if button:GetChecked() then
BagBuddy.qualityFilter = true
end
end
BagBuddy.page = 1
260 Part II Programming in World of Warcraft
BagBuddy Update()
end
function BagBuddy NextPage(self)
BagBuddy.page = BagBuddy.page + 1
BagBuddy Update(BagBuddy)
end
function BagBuddy PrevPage(self)
BagBuddy.page = BagBuddy.page - 1
BagBuddy Update(BagBuddy)
end
function BagBuddy ScanBag(bag, initial)
if not BagBuddy.bagCounts[bag] then
BagBuddy.bagCounts[bag] = {}
end
local itemCounts = {}
for slot = 0, GetContainerNumSlots(bag) do
local texture, count, locked, quality, readable, lootable, i
link = GetContainerItemInfo(bag, slot)
if texture then
local itemId = tonumber(link:match(“|Hitem:(%d+):“))
if not itemCounts[itemId] then
itemCounts[itemId] = count
else
itemCounts[itemId] = itemCounts[itemId] + count
end
end
end
if initial then
for itemId, count in pairs(itemCounts) do
BagBuddy ItemTimes[itemId] = BagBuddy ItemTimes[itemId] or time()
end
else
for itemId, count in pairs(itemCounts) do
local oldCount = BagBuddy.bagCounts[bag][itemId] or 0
if count > oldCount then
BagBuddy ItemTimes[itemId] = time()
end
end
end
BagBuddy.bagCounts[bag] = itemCounts
end
function BagBuddy OnEvent(self, event, ...)
Chapter 13 Responding to Game Events 261
if event == “ADDON LOADED“ and ... == “BagBuddy“ then
if not BagBuddy ItemTimes then
BagBuddy ItemTimes = {}
end
for bag = 0, NUM BAG SLOTS do
-- Use the optional flag to skip updating times
BagBuddy ScanBag(bag, true)
end
self:UnregisterEvent(“ADDON LOADED“)
self:RegisterEvent(“BAG UPDATE“)
elseif event == “BAG UPDATE“ then
local bag = ...
if bag >= 0 then
BagBuddy ScanBag(bag)
if BagBuddy:IsVisible() then
BagBuddy Update()
end
end
end
end
SLASH BAGBUDDY1 = “/bb“
SLASH BAGBUDDY2 = “/bagbuddy“
SlashCmdList[“BAGBUDDY“] = function(msg, editbox)
BagBuddy.input:SetText(msg)
ShowUIPanel(BagBuddy)
end
BagBuddy.xml
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Button name=“BagBuddyItemTemplate“ i
inherits=“SecureActionButtonTemplate“ virtual=“true“>
<Size>
<AbsDimension x=“37“ y=“37“/>
</Size>
<Layers>
<Layer level=“BORDER“>
<Texture name=“$parentIconTexture“ parentKey=“icon“/>
<FontString name=“$parentCount“ parentKey=“count“ i
inherits=“NumberFontNormal“ justifyH=“RIGHT“ hidden=“true“>
<Anchors>
<Anchor point=“BOTTOMRIGHT“>
<Offset>
<AbsDimension x=“-5“ y=“2“/>
</Offset>
262 Part II Programming in World of Warcraft
</Anchor>
</Anchors>
</FontString>
</Layer>
<Layer level=“OVERLAY“>
<Texture name=“$parentGlow“ parentKey=“glow“ alphaMode=“ADD“
file=“Interface\Buttons\UI-ActionButton-Border“>
<Size x=“70“ y=“70“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Color r=“1.0“ g=“1.0“ b=“1.0“ a=“0.6“/>
</Texture>
</Layer>
</Layers>
<Attributes>
<Attribute name=“type2“ type=“string“ value=“item“/>
</Attributes>
<Scripts>
<OnEnter function=“BagBuddy Button OnEnter“/>
<OnLeave function=“BagBuddy Button OnLeave“/>
</Scripts>
<NormalTexture name=“$parentNormalTexture“ i
file=“Interface\Buttons\UI-Quickslot2“>
<Size>
<AbsDimension x=“64“ y=“64“/>
</Size>
<Anchors>
<Anchor point=“CENTER“>
<Offset>
<AbsDimension x=“0“ y=“-1“/>
</Offset>
</Anchor>
</Anchors>
</NormalTexture>
<PushedTexture file=“Interface\Buttons\UI-Quickslot-Depress“/>
<HighlightTexture file=“Interface\Buttons\ButtonHilight-Square“
alphaMode=“ADD“/>
</Button>
<CheckButton name=“BagBuddyFilterTemplate“
inherits=“BagBuddyItemTemplate“ virtual=“true“>
<Scripts>
<OnEnter function=“BagBuddy Filter OnEnter“/>
<OnLeave function=“BagBuddy Filter OnLeave“/>
<OnClick function=“BagBuddy Filter OnClick“/>
</Scripts>
<CheckedTexture file=“Interface\Buttons\CheckButtonHilight“
alphaMode=“ADD“/>
</CheckButton>
Chapter 13 Responding to Game Events 263
<Frame name=“BagBuddy“ parent=“UIParent“ hidden=“true“>
<Size x=“384“ y=“512“/>
<Anchors>
<Anchor point=“CENTER“ relativePoint=“CENTER“
relativeTo=“UIParent“/>
</Anchors>
<Layers>
<Layer level=“BACKGROUND“>
<Texture name=“$parent Portrait“ parentKey=“portrait“
file=“Interface\Icons\INV Misc EngGizmos 30“>
<Size x=“60“ y=“60“/>
<Anchors>
<Anchor point=“TOPLEFT“>
<Offset x=“7“ y=“-6“/>
</Anchor>
</Anchors>
</Texture>
</Layer>
<Layer level=“OVERLAY“>
<FontString name=“$parent Title“ parentKey=“title“
inherits=“GameFontNormal“ text=“BagBuggy“>
<Anchors>
<Anchor point=“TOP“>
<Offset x=“0“ y=“-18“/>
</Anchor>
</Anchors>
</FontString>
<FontString name=“$parent Status“ parentKey=“status“
inherits=“GameFontHighlight“>
<Anchors>
<Anchor point=“CENTER“ relativePoint=“BOTTOM“>
<Offset x=“-10“ y=“150“/>
</Anchor>
</Anchors>
</FontString>
</Layer>
<Layer level=“BORDER“>
<Texture file=“Interface\BankFrame\UI-BankFrame-TopLeft“>
<Anchors>
<Anchor point=“TOPLEFT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-TopRight“>
<Anchors>
<Anchor point=“TOPRIGHT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-BotLeft“>
<Anchors>
264 Part II Programming in World of Warcraft
<Anchor point=“BOTTOMLEFT“/>
</Anchors>
</Texture>
<Texture file=“Interface\BankFrame\UI-BankFrame-BotRight“>
<Anchors>
<Anchor point=“BOTTOMRIGHT“/>
</Anchors>
</Texture>
</Layer>
</Layers>
<Frames>
<Button name=“$parent Close“ parentKey=“close“
inherits=“UIPanelCloseButton“>
<Anchors>
<Anchor point=“TOPRIGHT“>
<Offset x=“-30“ y=“-8“/>
</Anchor>
</Anchors>
</Button>
<Button name=“BagBuddy PrevButton“ parentKey=“prev“>
<Size x=“32“ y=“32“/>
<Anchors>
<Anchor point=“CENTER“ relativeTo=“BagBuddy“
relativePoint=“BOTTOMLEFT“>
<Offset>
<AbsDimension x=“50“ y=“150“/>
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick function=“BagBuddy PrevPage“/>
</Scripts>
<NormalTexture
file=“Interface\Buttons\UI-SpellbookIcon-PrevPage-Up“/>
<PushedTexture
file=“Interface\Buttons\UI-SpellbookIcon-PrevPage-Down“/>
<DisabledTexture
file=“Interface\Buttons\UI-SpellbookIcon-PrevPage-Disabled“/>
<HighlightTexture
file=“Interface\Buttons\UI-Common-MouseHilight“
alphaMode=“ADD“/>
</Button>
<Button name=“BagBuddy NextButton“ parentKey=“next“>
<Size x=“32“ y=“32“/>
<Anchors>
<Anchor point=“CENTER“ relativeTo=“BagBuddy“
relativePoint=“BOTTOMRIGHT“>
<Offset>
<AbsDimension x=“-70“ y=“150“/>
Chapter 13 Responding to Game Events 265
</Offset>
</Anchor>
</Anchors>
<Scripts>
<OnClick function=“BagBuddy NextPage“/>
</Scripts>
<NormalTexture
file=“Interface\Buttons\UI-SpellbookIcon-NextPage-Up“/>
<PushedTexture
file=“Interface\Buttons\UI-SpellbookIcon-NextPage-Down“/>
<DisabledTexture
file=“Interface\Buttons\UI-SpellbookIcon-NextPage-Disabled“/>
<HighlightTexture
file=“Interface\Buttons\UI-Common-MouseHilight“
alphaMode=“ADD“/>
</Button>
<EditBox name=“$parent Input“ parentKey=“input“
autoFocus=“false“>
<Size x=“400“ y=“20“/>
<Anchors>
<Anchor point=“BOTTOMLEFT“>
<Offset x=“32“ y=“100“/>
</Anchor>
</Anchors>
<Scripts>
<OnEscapePressed>
self:ClearFocus()
</OnEscapePressed>
<OnTextChanged>
BagBuddy Update()
</OnTextChanged>
</Scripts>
<FontString inherits=“GameFontHighlight“/>
</EditBox>
</Frames>
<Scripts>
<OnLoad function=“BagBuddy OnLoad“/>
<OnEvent function=“BagBuddy OnEvent“/>
</Scripts>
</Frame>
</Ui>
CHAPTER
14
Tracking Damage with
CombatTracker
You’ve worked through all of the different aspects of writing an addon while
creating the BagBuddy addon. You’ve learned how to use the WoW API to
query information from the game client, registered for and responded to game
events, and created widgets with which users can interact. In this chapter,
you’ll put all of these skills together to create an addon called CombatTracker.
Defining Specifications
Before sitting down to code, it’s important to understand exactly what an
addon will be expected to do and have a general idea of how it should operate
from the user perspective. What isn’t important at this stage is how you will
implement the addon; the design needs to be decided first.
CombatTracker User Experience
The specification for CombatTracker covers the following details:
1. A frame that can be dragged and moved by the user will be created on
screen.
2. When the player enters combat, the addon will store the current time and
change the frame to display ‘‘In Combat.’’
3. Each time the player takes damage from an NPC, the frame’s display will
be updated to show the amount of time that has been spent in combat,
the amount of damage that has been sustained, and the incoming damage
per second.
267
268 Part II Programming in World of Warcraft
4. When combat has ended, the frame will display final statistics.
5. The frame will be a button and, when clicked, will send the incoming
damage-per-second summary to the player’s party, if he is in one;
otherwise, it will simply be displayed on the screen.
Finding the Right Game Events
First figure out the events for which you will need to register. In this case,
you need to be notified of when the player enters or leaves combat. When in
combat, you need to know when the player takes damage. This section details
the three events that CombatTracker needs to function:
PLAYER_REGEN_DISABLED
PLAYER_REGEN_ENABLED
UNIT_COMBAT
PLAYER_REGEN_DISABLED
Upon entering combat, a player no longer regenerates health over the course
of time, with the exception of spells, talents, and equipment that provide
specific amounts of health regeneration every five seconds. As a result, the
PLAYER_REGEN_DISABLED event can be used to indicate when the player has
engaged in combat, according to the game client. This event doesn’t necessarily
mean that the player has sustained any damage; it just indicates to the game
client that the player is now considered to be in combat.
From a user interface perspective, this event also enables addon authors to
do any last-minute setup for any addons that use secure templates. You learn
more about secure templates in Chapter 15 but, in short, they allow for addons
to cast spells and target units through a special system that cannot be altered
while in combat. This event gives those addons one last chance to configure
themselves.
PLAYER_REGEN_DISABLED has no arguments included when it fires.
PLAYER_REGEN_ENABLED
The PLAYER_REGEN_ENABLED event fires when the player begins normal health
regeneration again. It means the player’s normal health regeneration has
started and is fired consistently when the player exits combat. As a result, it
can be used by an addon to track the player exiting combat (even though the
event isn’t named PLAYER_EXIT_COMBAT or something similar). The event has
no arguments included when it fires.
Chapter 14 Tracking Damage with CombatTracker 269
UNIT_COMBAT
Several events deal with the player sustaining damage, but you will be using
the UNIT_COMBAT event. Anytime a unit the player is interested in (such as
party members, raid members and their targets, and so on) has a change in
hit points that relates to combat, this event fires with the following arguments
describing the change:
unitThe identifier for the unit that experienced the change.
actionThe type of combat action that happened. Some example values
are the strings HEAL,DODGE,BLOCK,WOUND,MISS,PARRY,andRESIST.
modifierIf the action was a combat attack, it could possibly be a
glancing hit, critical hit, or crushing blow. Example values are the strings
GLANCING,CRUSHING,andCRITICAL.
damageThe amount of damage sustained, or the amount of health
healed.
damagetypeThe type of damage that occurred, using one of the follow-
ing number values:
0physical damage
1—holy damage
2fire damage
3—nature damage
4frost damage
5shadow damage
6—arcane damage
Creating the Addon’s Skeleton
Although the entire CombatTracker addon (and most addons, actually) could
be written in just a single Lua file or a single XML file, this implementation
will separate the design and layout of the frames from the code that defines
the addon’s behavior. Create your addon skeleton:
1. In your AddOns directory, create a new directory called CombatTracker.
2. In this new directory create a file called CombatTracker.toc,withthe
following content:
270 Part II Programming in World of Warcraft
## Interface: 30200
## Title: CombatTracker
## Notes: Tracks incoming DPS, and how long you spend in combat
CombatTracker.lua
CombatTracker.xml
3. Create an empty file called CombatTracker.xml, which will be used to
create the frames.
4. Create an empty file called CombatTracker.lua, which will be used to
define the addon’s behavior.
If you exit the game and open the WoW client backup, you should see
CombatTracker listed in the AddOn List along with the description, as shown
in Figure 14-1.
Figure 14-1: CombatTracker in the AddOn List
Defining CombatTracker’s XML Frame
Begin by adding the <Ui> element to CombatTracker.xml. Remember, this
should be the outermost element of every XML file:
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
</Ui>
Next, add the definition for the main frame. Following the specifications,
this frame needs to be clickable, so it will use the Button widget type. Add the
following code inside the <Ui> element:
<Button name=“CombatTrackerFrame“ parent=“UIParent“ enableMouse=“true“ i
movable=“true“ frameStrata=“LOW“>
<Size x=“175“ y=“40“/>
<Anchors>
<Anchor point=“TOP“ relativePoint=“BOTTOM“ relativeTo=“Minimap“>
<Offset x=“0“ y=“-10“/>
</Anchor>
</Anchors>
</Button>
Chapter 14 Tracking Damage with CombatTracker 271
This code defines a new Button called CombatTrackerFrame and defines its
size and placement along with some attributes:
nameDeclares a name for the frame. When the frame is created, the
global variable with this name will be set to the created frame so it can be
referred to in other code.
parentDefines the parent of a frame, used by the UI system to decide
the scale, opacity, and visibility of a frame. Frame parents are discussed
further in Chapter 10.
enableMouseEnables mouse input for the frame, allowing you to click
it and register for drag events.
movableTells the user’s interface that this frame is movable. This is
simply an on/off switch; you will have to write the code to actually
accomplish the movement on your own.
frameStrataFrames in the user interface can be layered so some frames
appear above or below others. The value of this attribute tells the UI what
strata the frame should be drawn on.
The default placement of the frame will be just below the minimap, but the
user can move it to a more desirable location.
Next give the frame some visible elements, so it can be seen on screen.
For this, you will use a special type of texture called a backdrop to provide a
background and border for the frame.
Defining a Backdrop
A backdrop is a special way to define a background for a frame. They consist
of background files (which are, shockingly, used for the background of the
frame) and edge files (which are used to place a border around the frame).
Add the following backdrop definition within the <Button> element, but after
the </Anchors> tag:
<Backdrop bgFile=“Interface\DialogFrame\UI-DialogBox-Background“ i
edgeFile=“Interface\DialogFrame\UI-DialogBox-Border“ tile=“true“>
<BackgroundInsets>
<AbsInset left=“11“ right=“12“ top=“12“ bottom=“11“/>
</BackgroundInsets>
<TileSize>
<AbsValue val=“32“/>
</TileSize>
<EdgeSize>
<AbsValue val=“32“/>
</EdgeSize>
</Backdrop>
272 Part II Programming in World of Warcraft
This sets up the frame to use the same background and border textures
as the default dialog box (the frame that pops up when you’re looting a
bind-on-pickup item). If you’re setting the backdrop using Lua instead of XML,
you’ll need to call the SetBackdrop() method, passing in a table definition
with the same information:
frame:SetBackdrop({
bgFile = “Interface\\DialogFrame\\UI-DialogBox-Background“,
edgeFile = “Interface\\DialogFrame\\UI-DialogBox-Border“,
tile = true,
tileSize = 32,
edgeSize = 32,
insets = {
left = 11,
right = 12,
top = 12,
bottom = 11,
}
})
Adding a Font String
Now that your frame has a background and border, you need to add a line of
text to display the combat information. Include the following code within the
<Button> after the </Backdrop> tag:
<Layers>
<Layer level=“OVERLAY“>
<FontString name=“$parentText“ inherits=“GameFontNormalSmall“ i
justifyH=“CENTER“ setAllPoints=“true“ text=“CombatTracker“/>
</Layer>
</Layers>
The code snippet defines a new graphical layer (at the OVERLAY level) and
creates a new FontString.
This completes the visual definition of the frame, so save the XML file and
log in to the game to see how it looks.
Testing CombatTrackerFrame
Before getting much further into the addon, log in to World of Warcraft to
verify that the XML definition is correct. You should see the minimap with the
new CombatTrackerFrame directly below it, similar to Figure 14-2.
Chapter 14 Tracking Damage with CombatTracker 273
Figure 14-2: CombatTrackerFrame anchored below the minimap
At this point, nothing can be done with the frame because no scripts have
been written to define its behavior. To make the addon fully functional, it
needs scripts to handle clicking, dragging, and handlers for events.
If for some reason you do not see the frame, check the Logs/FrameXML.log
file under your World of Warcraft directory. It may contain information about
any errors you have made in creating the file. Alternatively, you can validate
the file using one of the validation tools mentioned in Chapter 7.
Adding Script Handlers to CombatTrackerFrame
The behavior in this addon will be defined in CombatTracker.lua,butbefore
you can write those functions you must refer to them in the frame definition
in CombatTracker.xml.Openthe.xml file and add the following section right
after the </Layers> tag in the <Button> definition:
<Scripts>
<OnLoad>
CombatTracker_OnLoad(self)
</OnLoad>
<OnEvent>
CombatTracker_OnEvent(self, event, ...)
</OnEvent>
<OnClick>
CombatTracker_ReportDPS()
</OnClick>
<OnDragStart>
self:StartMoving()
</OnDragStart>
<OnDragStop>
self:StopMovingOrSizing()
</OnDragStop>
</Scripts>
274 Part II Programming in World of Warcraft
As mentioned in Chapter 8, each frame type has a number of widget scripts
that can be set with a handler function. Table 14-1 describes the scripts you’re
using here (you can find more details about these scripts and the arguments
they accept in Chapter 29, ‘‘Widget Reference’’).
Table 14-1: Script Handlers Used in CombatTracker
SCRIPT USE
<OnLoad> The basic initialization function for CombatTracker will
be called CombatTracker_OnLoad(). It’s called from
the <OnLoad> handler on the frame when the frame
has finished initializing. It works only for frames that are
defined in XML.
<OnEvent> The addon will respond to a number of events, so you
must define an OnEvent script to handle them. The
CombatTracker_OnEvent() function will be
responsible for each of the events. The handling function
will need to know which event it’s being passed, so
ensure you are passing the frame self, the event name
event, and the variable set of arguments ... to the
function.
<OnClick> When the player right-clicks CombatTrackerFrame,the
OnClick script handler will call the
CombatTracker_ReportDPS() function to print the
current combat status. The status message will be sent
to party chat if the player is in a party, otherwise it will be
printedtothechatframe.
<OnDragStart> The code for allowing a frame to be dragged and placed
is very simple, so the code is written directly in the script
handler rather than in a function defined in
CombatTracker.lua. Later, if you wanted to add
options to the addon, such as allowing the user to lock
the frame in place, you could move this code into the
Lua file to consolidate everything.
Each frame that has the movable attribute set to true
can call the self:StartMoving() method, which
causes the frame to follow the mouse. As a result, all
that’s required to set up frame movement when dragged
is to call this function.
<OnDragStop> Stopping the frame from moving is a matter of calling
self:StopMovingOrSizing(). This function also
flags the frame as user placed, meaning the next time
the addon loads, the frame will be put in the same place
the user dropped it. This is quite a handy side effect.
Chapter 14 Tracking Damage with CombatTracker 275
Adding Functions to CombatTracker.lua
To properly calculate the incoming damage, the time spent in combat, and the
average incoming DPS during combat, a few values need to be stored. These
will be created as local variables at the top of CombatTracker.lua.Openthat
file and add the following lines:
-- Set up some local variables to track time and damage
local start_time = 0
local end_time = 0
local total_time = 0
local total_damage = 0
local average_dps = 0
Four more functions must be created to have a fully functional addon:
CombatTracker_OnLoad(frame)
CombatTracker_OnEvent(self, event, ...)
CombatTracker_UpdateText()
CombatTracker_ReportDPS()
These functions are discussed in the following sections.
CombatTracker_OnLoad(frame)
As you may recall from your work in Chapter 4, the variable name self has a
bit of a special meaning in Lua. When a function inside a table is called using
the colon syntax, the first argument that Lua passes is the table itself with
the name self. In addition, when the World of Warcraft client calls a frame
script, the first argument is called self and points to the frame itself. This can
be confusing, so when you define functions that are called from XML, it is a
good idea to make the variable names more meaningful. In the script handler
for OnLoad, the script is given the frame object in the self variable, and will
pass it on to the CombatTracker_OnLoad() function. The function definition,
however, will name it frame. That way there’s no question about what type of
value it contains.
Add the following function definition to the bottom of CombatTracker.lua:
function CombatTracker_OnLoad(frame)
frame:RegisterEvent(“UNIT_COMBAT“)
frame:RegisterEvent(“PLAYER_REGEN_ENABLED“)
frame:RegisterEvent(“PLAYER_REGEN_DISABLED“)
frame:RegisterForClicks(“RightButtonUp“)
frame:RegisterForDrag(“LeftButton“)
end
276 Part II Programming in World of Warcraft
This function registers the combat tracker frame for the three events that
need to be watched. It also registers to receive right-click events, along with
drags with the left mouse button.
CombatTracker_OnEvent
The CombatTracker_OnEvent() function handles three different types of
events, so it will be one large conditional with special code for each event
name. Add the function as follows to the bottom of CombatTracker.lua:
function CombatTracker_OnEvent(frame, event, ...)
if event == “PLAYER_REGEN_DISABLED“ then
-- This event is called when we enter combat
-- Reset the damage total and start the timer
CombatTrackerFrameText:SetText(“In Combat“)
total_damage = 0
start_time = GetTime()
elseif event == “PLAYER_REGEN_ENABLED“ then
-- This event is called when the player exits combat
end_time = GetTime()
total_time = end_time - start_time
average_dps = total_damage / total_time
CombatTracker_UpdateText()
elseif event == “UNIT_COMBAT“ then
if InCombatLockdown() then
local unit, action, modifier, damage, damagetype = ...
if unit == “player“ and action ~= “HEAL“ then
total_damage = total_damage + damage
end_time = GetTime()
total_time = math.mind(end_time - start_time, 1)
average_dps = total_damage / total_time
CombatTracker_UpdateText()
end
end
end
end
The following sections explore the events handled by this function as
well as CombatTracker_UpdateText(), a function that’s called at the end of
CombatTracker_OnEvent().
PLAYER_REGEN_ENABLED
The PLAYER_REGEN_ENABLED section of the conditional happens when the
player exits combat, which means it’s time to clean up and display the final
results. The GetTime() function is used to set the end_time variable. It returns
the current value of the in-game timer. The actual value doesn’t matter because
Chapter 14 Tracking Damage with CombatTracker 277
you’re just going to subtract the start time from the end time to give you the
difference (in seconds).
Finally, the CombatTracker_UpdateText() function is called to handle the
update of the actual text on the frame. You could do the updating directly in
this function, but the same code will be needed at a later point. Rather than
having the same code in two places, it’s cleaner to make a new function that
does the common work.
PLAYER_REGEN_DISABLED
The PLAYER_REGEN_DISABLED event fires when the player enters combat, so
it needs to set up the accounting variables to ensure the addon gets a clean
slate for each combat. It simply calls CombatTrackerFrameText:SetText() to
change the frame to say ‘‘In Combat.’’ It also sets the total_damage variable
back to 0and initializes the start_time variable with the current time.
UNIT_COMBAT
Most of the addon’s logic actually happens in the UNIT_COMBAT section, so
it’s a bit larger than the other two. First you check to see if the player is in
combat (by checking the InCombatLockdown() function), so you can ignore any
messages that arrive outside of combat. Because event arguments are passed
to the function as a vararg, you assign them to named variables so they are
more easily accessible.
You’re interested only in those events that happen to the player and want
to skip those events in which the player is being healed, so check the unit and
action arguments. If both conditions pass, the current amount of damage is
added to the total, the end time is updated, and the total time and average DPS
are calculated. Because the time might be less than a second (and there is no way
to divide by zero) you use the math.min() function to choose either the time
difference, or 1, whichever is larger. Finally the CombatTracker_UpdateText()
function is called to update the frame.
CombatTracker_UpdateText()
CombatTracker_UpdateText() is a simple function that updates the status on
the CombatTrackerFrame using string.format(). Add the following function
definition to the bottom of CombatTracker.lua:
function CombatTracker_UpdateText()
local status = string.format(“%ds / %d dmg / %.2f dps“, i
total_time, total_damage, average_dps)
CombatTrackerFrameText:SetText(status)
end
278 Part II Programming in World of Warcraft
When run, this format string shows the number of seconds in combat,
followed by the amount of damage taken, and the average incoming DPS for
that combat period.
CombatTracker_ReportDPS()
The CombatTracker_ReportDPS()checks calls the GetNumPartyMembers() func-
tion to determine whether or not the player is in a party. If the number is
greater than 0, the player is in a party. Add the following function to your
CombatTracker.lua:
function CombatTracker_ReportDPS()
local msgformat = “%d seconds spent in combat with %d incoming i
damage. Average incoming DPS was %.2f“
local msg = string.format(msgformat, total_time, total_damage, i
average_dps)
if GetNumPartyMembers() > 0 then
SendChatMessage(msg, “PARTY“)
else
print(msg)
end
end
This function uses a format string to craft the outgoing message, and then
uses GetNumPartyMembers() to decide where to send it. If the player is in a
party, the SendChatMessage() function is used to send the message to the
party; otherwise, the print() function is used to send it to the chat frame so
the player can see it.
Testing CombatTracker
You have completed all the code necessary for a fully functional Combat-
Tracker addon. Load the game and select a character. You should be greeted
with the CombatTracker frame right below your minimap.
Testing is a very important part of addon writing if you plan to release your
addons to the public. When you write a set of features, it’s prudent to test
them yourself before you ship the addon to the public to ensure that users
won’t get error messages and be reporting them to you after the fact. That sort
of troubleshooting is always more difficult than errors you encounter on your
own. Systematically test each portion of the addon.
Chapter 14 Tracking Damage with CombatTracker 279
Frame Dragging
By clicking the frame, holding down the mouse button, and dragging your
mouse to another part of the screen, you should be able to move the Combat-
Tracker frame. Figure 14-3 shows it placed beneath the player frame.
Figure 14-3: CombatTracker anchored beneath the player frame
Just testing that the frame starts and stops dragging isn’t enough. Make sure
you can reload your UI and have the frame be restored to the new position
by running /console reloadui. This is a slash command that reloads all of
the Blizzard User Interface and all custom addon code. It’s quite useful when
making changes during development, or for testing purposes.
NOTE Once you’ve moved the frame from its initial anchored position, you may
need to adjust it any time you switch between windowed and full-screen mode, or
when you change screen resolution. You can re-anchor the frame to the minimap
with the following two slash commands:
/run CombatTrackerFrame:ClearAllPoints()
/run CombatTrackerFrame:SetPoint(“TOP“, Minimap, “BOTTOM“, 0, -10)
The first command clears any anchors the frame already has, and the second
command re-anchors the frame to the minimap, as was done originally in the
XML file.
Right-Click Reporting: Part I
The addon is set to print a status report or send it to your party chat when
CombatTracker is right-clicked. What happens if the user clicks the frame
before CombatTracker has had a chance to track any data? You can’t assume
your users will wait until they’ve already gone through combat to click, so test
that now.
Luckily, because of the way you initialized the local variables (with 0s), the
game can print a meaningful message, like the one shown in Figure 14-4.
280 Part II Programming in World of Warcraft
Figure 14-4: CombatTracker reporting before entering combat
Testing Combat Tracking
Log in to a character and go find something to fight. Hopefully, it’s something
you won’t have much difficulty killing but whose level is close enough to
yours that it can hurt you. Immediately upon entering combat, you should see
the frame change, as shown in Figure 14-5.
Figure 14-5: CombatTracker showing ‘‘In Combat.’’
After each hit of incoming damage, the frame should be updated to show
the current statistics. If you are fighting something from range, you won’t see
the frame update until the mob actually tries to hit you. Figure 14-6 shows
CombatTracker working in combat.
Figure 14-6: CombatTracker showing running statistics
Right-Click Reporting: Part II
When combat has ended, your frame updates with the final statistics and
remains there until you enter combat again or reload the user interface. There
is one more test that needs to be run on the right-click reporting, and that’s
making sure it displays correct statistics at the end of combat, and that it
properly sends a message to party chat when the player is in a party.
Chapter 14 Tracking Damage with CombatTracker 281
Figure 14-7 shows CombatTracker reporting before joining a party, as well
as after joining forces with another player.
Figure 14-7: CombatTracker reporting both in and out of a party
Summary
Creating an addon involves making decisions about the user experience and
scope of the addon, investigating what functions and events are required
to make the addon functional, and writing the addon itself. The process of
deciding how the user will experience your addon and what features make it
into the final product is often the most difficult part of writing an addon.
The next chapter explains the intricacies of frames, widgets, and other
graphics elements in depth.
Part
III
Advanced Addon Techniques
In This Part
Chapter 15: Taking Action with Secure Templates
Chapter 16: Binding Keys and Clicks to Addon Code
Chapter 17: Creating Slash Commands
Chapter 18: Responding to Graphic Updates with OnUpdate
Chapter 19: Altering Existing Behavior with Function Hooking
Chapter 20: Creating Custom Graphics
Chapter 21: Responding to the Combat Log and Threat Information
Chapter 22: Creating Scroll Frames
Chapter 23: Creating Dropdown Menus
Chapter 24: Scanning and Constructing Tooltips
Chapter 25: TakingProtectedActioninCombat
Chapter 26: Creating Unit Frames with Group Templates
CHAPTER
15
Taking Action with Secure
Templates
The design of World of Warcraft mandates that any meaningful action that
can affect the game world, such as casting a spell, using an item, or attacking
an enemy, be triggered by the player clicking a button or pressing a key
bound to that action. This was originally only mentioned in the terms of use,
which forbid any form of automation; but as the game developed, it became
clear that the requirement needed to be enforced in the Lua scripting engine.
This restriction is carried out by a system of trusted and untrusted code,
which prevents addons from taking these actions for the player, as well as a
mechanism called secure templates that allows addons to safely modify how the
player interacts with the game, without enabling automation.
In this chapter, you learn how to create and customize your own buttons that
the player can use to take in-game actions; you also learn what actions your
addons can take directly and which you must assign to a button for the player.
In addition you’ll discover how to troubleshoot problems that can occur due
to the differences between trusted (Blizzard) and untrusted (addon) code.
Why Are Secure Templates Necessary?
Although World of Warcraft offers an enormous variety of activities for its
players to engage in, fighting with creatures or other players holds the most
excitement and interest for most players. Combat is the most common activity
in the game, and the most sensitive. Decisions made on a split-second basis
determine whether you win a battleground, defeat a raid boss, or destroy a
quest mob; or whether you lie broken on a lost battlefield, run out of mana
285
286 Part III Advanced Addon Techniques
while healing your tank, or spend time running back to your corpse for ‘‘just
one more try.’’
While the initial version of WoW matured and addon authors became more
experienced, many addons were created that took action for the players. Some
addons were written to automatically decide what healing spell to cast on
whom, to provide the most effective healing in a party or raid. Other addons
were written that could run the player from one location to another (for
example, running your ghost to its corpse or from city to city).
As these addons became more widespread, WoW designers and developers
became concerned that they actually destroyed the fun of playing the game.
They certainly made victory easier, but players no longer needed to even pay
attention to the game they were playing. Over the course of several patches,
the designers took steps to reduce addons’ capability to make such decisions,
culminating in the patch 2.0 security model.
Under this model, all code that is supplied with the game is considered secure,
whereas code provided by addons is insecure or tainted.Onlysecurecodecan
call certain API functions such as casting a spell or using an item. Moreover,
if insecure code tries to interfere with secure code, its taint will spread to
the secure code and prevent the spell, item, or other secured operation from
working. This stops addons from exploiting the default user interface to bring
back addon automation.
As you’ll see, the security model is fairly complex. Needless to say, it would
have been easier for Blizzard to simply eliminate the capability for users to
write custom addons, but there is plenty to be gained by allowing for rich
customization of the user experience. Instead, Blizzard introduced a very
restrictive security model, but offers a number of secure templates that provide
a system for addon authors to take certain approved action, with limits. These
templates are pre-programmed, using attributes to determine what spell to
cast or other action to take, whom to cast it on, and other similar information.
Although addons can change the attribute values without tainting the secure
script’s capability to do its job, they can only do so under controlled conditions
(typically outside of combat), because the secure frames are protected.
Protected Frames
Aprotected frame is one that is capable of taking restrictive action, as defined by
the developers. During combat, only secure code can create, modify, or control
these frames, preventing addon code from doing things such as placing the
‘‘right’’ action button or unit frame under your mouse so the player can just
mindlessly click. However, unlike truly protected functions like CastSpell(),
these restrictions are lifted outside of the combat, allowing addons to create
new frames, move frames around, and reconfigure attributes.
Chapter 15 Taking Action with Secure Templates 287
If an addon (or the user) tries to make a restricted change on a frame during
combat, the user interface will display a notification in the chat frame, rather
than popping up a distracting notification. You will learn more about these
‘‘blocked addon’’ messages, and the taint log that can be used to troubleshoot
them, later in this chapter.
When a frame is protected, any frame that it is parented or anchored to
is also implicitly protected. This makes sense because otherwise you’d be
able to move or hide the unprotected frame to defeat the restrictions. Luckily
there is an widget method that allows you determine if a frame is protected
(either implicitly or directly): Frame:IsProtected(). The function returns two
values:
isProtected1if the frame is protected and subject to the restrictions
of protected frames; otherwise nil.
explicit1 if the frame is explicit; nil if the frame is only protected
implicitly due to a relationship with another frame.
Frame methods that affect positioning, visibility, interactivity, or secure
control are restricted from being called on protected frames during combat.
Here’s a list of those methods:
AllowAttributeChanges Lower SetHorizontalScroll
ClearAllPoints Raise SetParent
Disable SetAllPoints SetPoint
Enable SetAttribute SetScale
EnableKeyboard SetFrameLevel SetToplevel
EnableMouse SetFrameStrata SetVerticalScroll
EnableMouseWheel SetHeight SetWidth
Hide SetHitRectInsets Show
The protection itself is accomplished by defining an XML template with the
protected attribute set to true. This feature is not exactly useful for our own
purposes; the true power comes to us indirectly via secure templates.
NOTE It is possible to create code that modifies protected frames in combat,
under certain restrictions. WoW 3.0 introduced a system called secure handlers,
which allows you to submit code for secure execution on frames, as long as it
follows the designers’ guidelines on what is permitted in combat; this system is
covered in detail in Chapter 25.
288 Part III Advanced Addon Techniques
Controlling Secure Frames Using Attributes
As mentioned in the last section, secure templates are pre-configured using
named attributes. Unlike local or global variables, or keys set in frame tables,
they cannot be tainted. This allows data to be passed from insecure code
(addons) to secure code (secure templates) without compromising security.
Setting attributes on a frame is a restricted action, and insecure code can’t do
it during combat, as we’ve already said.
Frame attribute can be set by using the SetAttribute() method, or by using
the <Attribute> element in XML. For example:
frame:SetAttribute(“spell“, “Flash Heal“)
or
<Attributes>
<Attribute name=“spell“ type=“string“ value=“Flash Heal“/>
</Attributes>
You can obtain the value of an attribute using the GetAttribute() method.
The usage is fairly simple:
value = frame:GetAttribute(“spell“)
The value of an attribute can be any kind of Lua table, but the name is
always a string. Unlike most Lua conventions, name is not case-sensitive; if you
call frame:SetAttribute(“item“, “5“),frame:GetAttribute(“ITEM“) will
return the string “5“.
Whenever a frame is set on a frame, the frame’s OnAttributeChanged handler
script is called, allowing code to react to attribute changes. Attributes don’t
carry taint, so the OnAttributeChanged script can be used to trigger secure
code in response to an addon setting an attribute. The script is passed the
frame object, the name of the attribute, and the value. Despite attribute names
being case-insensitive, the name argument to an OnAttributeChanged script
will always be lowercase.
WARNING The choice of the word ‘‘attribute’’ is appropriate, but potentially
confusing, because in XML lingo, ‘‘attribute’’ is the term that describes the
properties given to an element within the element’s start tag (for example,
name=“$parentButton“, and so on). They are similar in that they associate a
value with a name and a parent object. Where it is important, we will discriminate
them with the terms frame attribute and XML attribute.
Using Secure Templates
Using secure templates doesn’t magically make your code secure. Code that
is created from your addon will always be considered tainted, and won’t be
Chapter 15 Taking Action with Secure Templates 289
able to defeat the secure restrictions. Secure templates are useful because they
contain a number of pre-written widget scripts that are still secure, and thus
can take restricted action based on attributes.
Although there are several secure templates defined in FrameXML\Secure
Templates.xml and FrameXML\SecureHandlers.xml, this chapter focuses on
one of the more widely used templates, SecureActionButtonTemplate.The
template definition is very simple, just calling SecureActionButton_OnClick
when the button is clicked.
Create your own frame or template that inherits from SecureActionButton
Template, and it will securely call SecureActionButton_OnClick when clicked,
as long as you do not assign your own OnClick handler. Each frame can have
only one handler per widget script, so setting a new one would remove the
secure version that actually does the work!
Defining Behaviors for Action Buttons
How are the secure templates programmed using frame attributes? The easiest
way to show how they are used is with an example. Run the following code in
game to create a new secure action button for you to work with:
SABTest = CreateFrame(“Button“, “SABTest“, UIParent, i
“SecureActionButtonTemplate,UIPanelButtonTemplate2“)
SABTest:SetWidth(80)
SABTest:SetHeight(20)
SABTest:SetText(“SABTest“)
SABTest:SetPoint(“CENTER“, 0, 0)
SABTest:SetAttribute(“spell“, “Attack“)
SABTest:RegisterForClicks(“AnyUp“)
Because secure templates provide no visual appearance themselves, you’ll
normally need to add some elements to make the button visible. You can do
this by adding layers and texture as per usual, but here you just inherit from a
template that already has visual components.
Everything here should seem familiar, other than the SetAttribute call at
the end. In this case, you’re setting the spell attribute to the string Attack.
That tells the secure action button’s OnClick handler to cast the Attack spell,
which starts or stops the player’s auto-attack, when the button is programmed
to cast a spell.
NOTE The type tag attribute has a default value of string,andan
overwhelming portion of the frame attributes used by the secure templates are
expected to contain strings, so in practice it is almost always omitted.
Casting a Spell
Once you’ve run the code, you should have a small, red button (see Figure 15-1)
in the middle of your screen that does nothing when clicked. Although you’ve
290 Part III Advanced Addon Techniques
programmed the button to cast Attack when it’s casting a spell, you haven’t
told it that it should be casting a spell.
Figure 15-1: A simple action button
Run the following command:
/run SABTest:SetAttribute(“type“, “spell“)
This corrects the omission by telling the button that when it is clicked it
should try to cast a spell. If you find an enemy and click the button, your
auto-attack should be toggled on or off.
Casting a Beneficial Spell
If you have a character that can cast beneficial spells (healing, cleansing, or
buffing), you can set your button up to cast that spell on yourself. Change the
spell attribute to the beneficial spell (changing Renew to the name of the spell):
/run SABTest:SetAttribute(“type“, “spell“)
/run SABTest:SetAttribute(“spell“, “Healing Wave“)
This tells the button to cast a spell when clicked, and specifies that the
Healing Wave spell should be cast. If you find and target a friendly target, you
can click the button, and the spell should be cast on your targeted unit.
You can specify the unit to target with an action by using the unit attribute.
Run the following:
/run SABTest:SetAttribute(“unit“, “player“)
Now whenever you click the button, the spell will be cast on you. This
illustrates just one of the many ways multiple attributes on the same frame
can interact to bring varied results.
Casting a Harmful Spell
The same principle can be used to cast a harmful spell on a target. Run the
following to change the attributes:
/run SABTest:SetAttribute(“spell“, “Lightning Bolt“)
/run SABTest:SetAttribute(“unit“, “target“)
Looking Under the Hood
So what is actually going on when you click your button? The code can be found
in FrameXML\SecureTemplates.lua,intheSecureActionButton_OnClick()
Chapter 15 Taking Action with Secure Templates 291
function. It may be a bit difficult to follow along (the buttons are very
powerful), but here are the basic steps:
1. The type attribute is checked to determine which type of action to take.
In this case, your button is set to cast a spell by using the spell type.
2. The spell attribute is retrieved to determine what spell to cast.
3. The unit attribute is checked to see if you’re specifying a particular unit
on which to cast the spell.
4. The CastSpellByName is called securely with the name of the spell and,
optionally, the unit.
This is where the nature of protected frames, protected functions, taint,
and attributes finally come together. Only secure code is allowed to call
CastSpellByName.BecausetheSecureActionButton template is defined in the
FrameXML, it and all of its handlers are secure. The template has the protected
attribute set to true, so any frame that inherits from this template will also be
protected. The SetAttribute method is protected outside of combat, which
means Blizzard can precisely control when and how the player is allowed to
configure the buttons that take protected action.
Specifying Units to Affect
Many templates can act on units in various ways. For example, quite a few
types of SecureActionButtons do their actions on the specified unit. You
can control the unit directly via the unit attribute, which was shown in the
previous example.
Alternatively, if you use a “unitsuffix“ attribute, its value will be appended
to the “unit“ attribute of the button’s parent. Chapter 26 shows you how to
use this attribute to create child pet frames for a set of unit frames without
having to manually specify the pet units.
You can also make the button respond to your self-cast modifier by setting
its “checkselfcast“ attribute to a true value.
Other Types and Their Uses
If you look at the source for the SecureActionButton template, you likely
noticed the table SECURE_ACTIONS that is defined. Each entry in this table
defines a new type that is recognized by the secure template, and defines a set
of subordinate attributes that further control the button’s behavior.
The following is a list of the type attributes that are accepted by the
SecureActionButton template, and a list of the sub-attributes that further
customize that secure action. Types marked with a (U) respond to the unit
attribute and equivalents, if present.
292 Part III Advanced Addon Techniques
actionbarUsed to manipulate your action bar page.
actionDescribes how to change the action bar page. A single number
means change directly to that page. A string with two numbers sep-
arated by a comma (for example, “1, 2“) will swap between the two
given pages. It will switch directly to the first number if you are on a
page other than the two given. Finally, you can use either “increment“
or “decrement“ to go up one page or down one page, respectively. They
will both wrap to the other end if you go too far.
action (U)Activates an action slot. Subordinate attribute:
action (optional)The action slot number to use. If you omit this
attribute, the action will be determined by the button’s ID in the
same manner as the default UI. In other words, if you have a button
with an ID of 1, the actual action used would depend on your stance,
action bar page, and so on, just like the first button on the main action
bar. See UseAction (API) for more information.
pet (U)Uses one of your pet’s abilities. Subordinate attribute:
actionThe pet action index of the ability you wish to use. See
CastPetAction (API) for more information.
multispellConfigures a multi-cast action slot to use a specific spell.
Subordinate attributes:
actionThe multi-cast action slot you would like to configure.
spellThe spell you would like to configure for the given action slot.
spell (U)Casts the named spell. Subordinate attribute:
spellThe name of the spell to cast. See CastSpellByName (API) for more
information.
item (U)Uses the given item. Subordinate attributes (two deprecated
attributes you may notice in the FrameXML code are intentionally
omitted):
itemSpecifies the item to use. This attribute can take a number of forms
depending on how you want to access the item:
“Name of Item“—By name.
“item:12345“—By item ID.
“13“By inventory slot number for equipped items.
“3 12“By bag and slot number for items in your bags.
macroRuns a macro. Subordinate attributes:
macroThe macro to run. This can be the numerical index or the name
of a macro to run.
Chapter 15 Taking Action with Secure Templates 293
macrotextThe text of a macro. Set this to a Lua string containing the
macro you want to run. This text is limited to 1023 bytes (usually
but not always single characters). A “macro“ attribute will override a
“macrotext“ one.
cancelauraRemoves a buff from the player, including secured buffs such
as druid forms. Subordinate attributes:
indexThe number of the buff to remove from the player, in an arbitrary
order.
spellThe name of the buff to be removed. Ignored if index is present.
rankThe rank of buff to remove. Ignored if index is present.
stopCancels the target selection cursor (glowing blue hand). No subordi-
nate attributes are used.
target (U)Manages unit targeting. If the unit attribute is set to none, the
action will clear the player’s target. If the player has a spell that is awaiting
a target (showing the glowing hand), the action will choose the target for
that spell. If the player’s cursor is holding an item, this action will drop
the item on that unit (initiate trade, equip, and so forth). Otherwise, this
action just targets the specified unit.
focus (U)Focuses on the given unit.
assist (U)Assists the specified unit.
maintank (U)Sets the unit as a main tank for the raid. Subordinate
attribute:
actionA string indicating what assignment action should be taken:
setSets the role on the given unit.
clearClears the role from the given unit.
toggleToggle the role for the given unit.
mainassist (U)Sets the unit as a main assist for the raid.
actionA string indicating what assignment action should be taken:
setSets the role on the given unit.
clearClears the role from the given unit.
toggleToggle the role for the given unit.
clickSecurely simulates a click on another button. Subordinate attribute:
clickbuttonThe button to click. This must be a direct reference, not the
name of the button.
294 Part III Advanced Addon Techniques
attributeSecurely sets an attribute on a frame, allowing one button
to configure another. Useful in combination with state handlers (see
Chapter 25). Subordinate attributes:
attribute-frameA direct reference (not by frame name) to the frame on
which an attribute will be set. If this is nil, it defaults to the button
itself.
attribute-nameThe name of the attribute to set.
attribute-valueThe value to set the attribute to.
If the type attribute is set to something other than one of these predefined
actions, such as ‘‘reveal’’, the button will check the following places:
self:GetAttribute(“_reveal“)
self[“reveal“]
If the value stored is a function, it will call the function passing in the
following arguments:
The button object itself.
The unit attribute, if set.
The mouse click that triggered the click handler.
If the value is a string, the secure handler will dispatch the contents of the
string as a secure handler _onclick call, covered in Chapter 25.
This method of function dispatch is used by the default user interface to
display the popup menus for unit frames.
Item Targets
If an action you are taking can target an item instead of a unitusing a poison,
for exampleyou can use the following attributes to specify what item to
target:
target-slotAn inventory slot number by itself, or a bag slot number
along with target-bag.
target-bagSpecifies a bag number (04, right to left on the default bag
bar). You must also include a target-slot attribute.
target-itemThe name of the item.
Using an ‘‘item’’ Type Button
Using the SABTest button you created earlier, run the following commands
in-game to set up some new behavior on your button. You’ll want to run these
tests on a character that has some bandages to spare so you can see the full
effect. Wherever you see Heavy Frostweave Bandage in the following code
samples, rename it to whatever bandages you have available.
Chapter 15 Taking Action with Secure Templates 295
/run SABTest:SetAttribute(“type“, “item“)
/run SABTest:SetAttribute(“item“, “Heavy Frostweave Bandage“)
/run SABTest:SetAttribute(“unit“, “player“)
The first line tells the button to use an item when it’s clicked. The second
specifies the bandages you want to use. Finally, the unit attribute tells the
button to use the item on the player. If your bandages were in the first slot of
your backpack, you could use an item attribute of “0 1“ instead of the name
of the bandage, and it would always use whatever was in that slot.
Because bandages can only be used when you’re missing some health, you’ll
want to head out into the wilderness and pick a fight with some easy mob.
There are plenty of other creative ways to reduce your health percentage (such
as un-equipping and re-equipping a piece of stamina gear). Whenever you feel
like bandaging yourself, click the SABTest button and enjoy.
Using an Item with a ‘‘macro’’ Type Button
If you have spent any time in the UI customization community before diving
into addon programming, you should be at least marginally familiar with
macros. One very simple example is a self-use macro. On an action button
this macro will behave exactly like the SABTest example from the preceding
section.
/use [target=player] Heavy Frostweave Bandage
Attaching this macro to the SABTest button is fairly straightforward:
/run SABTest:SetAttribute(“type“, “macro“)
/run SABTest:SetAttribute(“macrotext“, i
“/use [target=player] Heavy Frostweave Bandage“)
Notice that even if you still have the unit attribute from the previous
self-bandage configuration, it will be completely ignored. “macro“ type action
buttons leave that sort of decision entirely up to the macro itself.
NOTE A thorough treatment of the macro system is beyond the scope of this
book. However, you can find further information in several places. Blizzard
provides an introductory macro guide at
http://worldofwarcraft.com/info/basics/macros.html. Although it does
not currently cover conditional macros, it has been updated with excellent basic
information.
Cogwheel, a member of the WoW UI community, also created Cogwheel’s Complete
Macro Guide, which currently resides at www.wowwiki.com/Making amacro.As
far as we know, its creator no longer maintains the page but it remains one of the
most comprehensive guides to WoW macros available, with detailed descriptions
of all the common (and many obscure) slash commands and macro options.
296 Part III Advanced Addon Techniques
Making Simple Choices
Writing addons that take protected actions is great, but what you’ve seen
so far is not very flexible. Sure, you can configure a button any way you
wantwhile you’re out of combat. And that’s the real trick: to make an addon
behave even like the default UI, you have to be able to make certain changes
during combat. A action bar addon needs to change pages when you switch
forms. Unit frames that you can actually click to target need a way to show
and hide themselves.
Covering all of the possible options in this chapter isn’t very practical
(the secure snippets system is covered in Chapter 25), but this section does
introduce you to two of the most frequently used options for secure templates:
modifier keys and mouse buttons.
Working with Modified Attributes
The attributes you’ve worked with so far are universal. That is, there can
be only one unit attribute set on a given frame. The default user interface
allows you to take different action depending on whether you’ve right-clicked
or left-clicked a frame. Addons using secure templates can make a similar
distinction, and also add the capability to use modifier keys (Alt, Ctrl, and
Shift) to select the correct action.
Format of a Modified Attribute
If you call the attributes you’ve worked with so far root or unmodified attributes,
then a modified attribute consists of a prefix, followed by the root, followed by
asufx.
PrefixDetermines which modifier keys to check. The prefix doesn’t
have to be set, but should have a hyphen (dash) after it if it does.
RootThe name of the root or unmodified attribute, the object that the
prefix and suffix modify.
SuffixThe mouse button that can be used to trigger this action. If this
attribute isn’t included, it will default to any mouse button. You can also
specify this explicitly by using an asterisk (*) as a wildcard.
For example, set up your SABTest button with the following attributes (set
up for a Level 2 Priest):
/run SABTest:SetAttribute(“type“, “spell“)
/run SABTest:SetAttribute(“spell“, “Lesser Heal“)
/run SABTest:SetAttribute(“unit“, “player“)
/run SABTest:SetAttribute(“shift-type1“, “spell“)
/run SABTest:SetAttribute(“shift-spell1“, “Power Word: Fortitude“)
This configures the button to cast Lesser Heal on the player when clicked
with the left button, but when Shift+left-clicked, it casts Power Word: Fortitude
Chapter 15 Taking Action with Secure Templates 297
on the player instead. For the last attribute, the prefix is shift, the root attribute
is spell, and the prefix is 1.
The prefix can be any combination of alt,ctrl,andshift, chained together
with hyphens. They must appear in alphabetical order, so the combination of
AltandShiftwouldbealt-shift and Alt, Ctrl, and Shift together would be
alt-ctrl-shift. The mouse button is just a number that maps to a specific
mouse button.
Inheritance of Attributes
Attributes have some default inheritance that can make it easier to set things
up. For example if you were to right-click the SABTest button while holding
your Ctrl and Alt keys, it will check for the following “spell“ attributes
in order:
1. alt-ctrl-spell2
2. *spell2
3. alt-ctrl-spell*
4. *spell*
5. spell
Remember that an asterisk (*) is used to match any prefix or suffix.
You can also map modifier keys to arbitrary names by using a “modifiers“
attribute on the button. This attribute uses the following format, with items in
brackets ([]) being optional:
MODIFIER[:name][,MODIFIER[:name]]...
MODIFIER can be a normal modifier (ALT,CTRL,orSHIFT)oramodier
variable, such as SELFCAST.SeeIsModifiedClick (API)fordetails.Ifnoname
is specified, the lowercase version of the modifier will be returned. For example:
SPLITSTACK:split,ALT
This value will give a prefix of “split-“ if you are holding down the
stack-splitting modifier or “alt-“ if you are holding the Alt key.
Choosing an Action by Mouse Button
You have most likely guessed that to pick a spell based on a mouse button you
need to specify a suffix. The most basic suffixes are the numbers 1 to 5, which
indicate mouse buttons:
1. Left button
2. Right button
3. Middle button
4. Button 4
5. Button 5
298 Part III Advanced Addon Techniques
WARNING The prefix/suffix system is a bit stricter than you might first assume.
The five attribute variations mentioned earlier create some specific situations
worth noting. For example, although you can use “spell“ as a last resort fallback,
“spell2“ will match only if you’re not holding any modifier keys.
When in doubt, decide whether it is more appropriate for you to use wildcards, or
strict attributes.
Delegating Attribute Responsibility
If you have a number of secure action buttons that are closely related,
perhaps an action bar, modified attributes provide a “useparent“ facility to
delegate an attribute to the button’s parent, which makes it easier to apply
configurations to multiple buttons. If SecureButton_GetModifiedAttribute
does not find a match with one of the five variations, it will check for a
“useparent-rootor “useparent*“ attribute. If it finds one, it will get the
modified attribute from the parent.
For example, the default UI’s action buttons have a “useparent-unit“
attribute. With one simple setting, you can make all of the buttons on the main
bar cast normally with a left-click, or always on yourself with a right-click:
/run MainMenuBarArtFrame:SetAttribute(“*unit2“, “player“)
Choosing an Action by Hostility
You can customize the ‘‘mouse button’’ in a way that is checked against the
suffix.
Two new attributes allow you to change the nature of the button based
on the nature of the specified unit: “helpbutton“, meaning you can cast
beneficial spells on the unit, and “harmbutton“, meaning you can attack the
unit. The value of these attributes is a string that will be used for the suffix in
subsequent modified attribute checks. You can continue the previous example
with Shadow Word: Pain and Power Word: Shield by making a single button
that automatically picks between the two:
/run SABTest:SetAttribute(“unit“, “target“)
/run SABTest:SetAttribute(“harmbutton“, “nuke“)
/run SABTest:SetAttribute(“helpbutton“, “heal“)
/run SABTest:SetAttribute(“*spell-nuke“, “Shadow Word: Pain“)
/run SABTest:SetAttribute(“*spell-heal“, “Lesser Heal“)
Some targets can be neither helped nor harmed (neutral NPCs, for instance).
In cases like that, the preceding example will do nothing. You must explicitly
set a unit attribute; otherwise helpbutton and harmbutton will be ignored.
It is worth noting that “helpbutton“ and “harmbutton“ themselves can also
be modified. That way you can create different suffixes depending on which
actual mouse button was used to click the button.
Chapter 15 Taking Action with Secure Templates 299
Applying Action Buttons in Practice
At this point, all the fundamentals of the secure template system have been
covered. Now that you have a grasp of the various interactions among
attributes, suffixes, protected frames, and taint, you can put it into practice by
making changes to existing action buttons and creating new ones.
Modifying an Existing Frame
The standard behavior of a unit frame is to target its unit when left-clicked. The
target frame also follows this convention, even though targeting your target
is not normally a useful action. You can reclaim some of that ‘‘click-space’’
by typing the following into WoWLua (if you’re over level 8 or so, substitute
whatever sort of bandage you’re currently using):
/run TargetFrame:SetAttribute(’item’, “Linen Bandage“)
/run TargetFrame:SetAttribute(’shift-type*’, 'item’)
/run TargetFrame:SetAttribute(’ctrl-type*’, 'item’)
/run TargetFrame:SetAttribute(’alt-type*’, 'item’)
The plain click is left as a target action because it is still useful to take
action on your current target if you have, say, a beneficial spell ready to cast
(your cursor shows the blue glow). But now, when you left-click your target’s
portrait with a modifier down, you’ll bandage your target. Right-clicking
your target still brings up his unit menu, with raid marker options and so
on. That’s because TargetFrame inherits from SecureUnitButtonTemplate,a
special subspecies of SecureActionButtonTemplate designed for unit frames
that sets the *type2 attribute to a menu function.
NOTE There is a slightly simpler, but less intuitive way to define bandaging as
the behavior on any modified click, and that is to set the 'type’ or '*type1
attributes to 'item’ and the 'type*’or'type1' attributes to ‘target’.That
way, the target action is selected only when the click is actually unmodified.
If you have several changes to make to a frame, you may find it useful to
add a SetFrameAttributes function like this one:
function SetFrameAttributes(self, attributes)
for name, value in pairs(attributes) do
if type(name) == 'string’ then
self:SetAttribute(name, value)
end
end
end
TargetFrame.SetAttributes = SetFrameAttributes
300 Part III Advanced Addon Techniques
That enables you to set multiple attributes with an understandable list
format:
TargetFrame:SetAttributes{
unit = 'target’, -- this was also preset by the frame definition
type = 'target’, -- so was this
[’*type2’] = 'menu’, -- and this
item = 'Linen Bandage’,
[’shift-type*’] = 'item’,
[’ctrl-type*’] = 'item’,
[’alt-type*’] = 'item’
}
This approach generates a throw-away table; it’s suitable for one-time or
otherwise infrequent setup, but should be avoided for frequent changes.
A Complex Action Button
The last example for this chapter builds a single button from scratch that
can cast one of three spellsdepending on what modifier keys are heldon
one of three friendly targets, depending on which mouse button was used
and whether the target was friendly. The example uses priest abilities; feel
free to adjust the attributes to your liking and experiment with different
configurations.
This mini-addon adds an action button to the lower-left region of the screen.
Click it to cast the spell Greater Heal; Shift+click for Power Word: Shield; and
Ctrl+click for Renew. Moreover, it offers some more options on who to heal
or protect: while it usually casts on your target, right-clicking casts on your
focus, and clicking while you have an enemy targeted automatically casts on
yourself, without changing your target.
Here’s what to do:
1. Create a directory called QuickCasterButton in your Interface\AddOns
directory.
2. Create a file inside this new directory named QuickCasterButton.toc,
containing the following lines:
## Interface: 30300
## Title: QuickCasterButton
## Notes: Casts a variety of helpful spells on different targets
QuickCasterButton.xml
3. Create another file in the same directory named QuickCasterButton.xml,
andopenitinatexteditor.
Chapter 15 Taking Action with Secure Templates 301
4. Enter the beginning tags for the UI definition (required for any addon
XML file) and the button frame:
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
This example illustrates one of the most common uses of SecureAction
ButtonTemplate, which is to marry it to ActionButtonTemplate via
multiple inheritance; this creates a button that has the ‘‘look and
feel’’ of the stock action buttons pre-built. The commonly used
ActionBarButtonTemplate begins with these two templates, and then
adds functions to keep the buttons’ appearance up-to-date with what
they do. In this case, using the templates directly keeps things simple.
5. Enter the anchor code to place the button in the lower left:
<Anchors>
<Anchor point=“BOTTOMLEFT“ relativeTo=“UIParent“>
<Offset x=“180“ y=“280“ />
</Anchor>
</Anchors>
6. Open the <Attributes> tag and define the button as a spell button:
<Attributes>
<Attribute name=“type“ value=“spell“ />
7. Define the default spell for the button, as well as spells for Shift+click
and Ctrl+click:
<Attribute name=“spell“ value=“Greater Heal“ />
<Attribute name=“shift-spell*“ value=“Power Word: Shield“ />
<Attribute name=“ctrl-spell*“ value=“Renew“ />
8. Now define the units for the button to affect. nil is usually the same as
“target“,butforharmbutton to work in the next step, an actual target
needs to be defined:
<Attribute name=“unit“ value=“target“ />
<Attribute name=“*unit2“ value=“focus“ />
A very powerful technique is to vary one attribute according to the mod-
ifier and another one according to the button. In this example, the mouse
button clicked specifies the unit to cast on, and the modifiers choose the
spell to cast. In this way, a whole grid of unit-spell combinations can be
created with comparatively few frame attributes.
302 Part III Advanced Addon Techniques
9. Define the name of the button you want used when the target is an
enemy, and then define the unit to use when that button is clicked:
<Attribute name=“harmbutton“ value=“self“ />
<Attribute name=“*unit-self“ value=“player“ />
10. Close the Attributes section and start a Scripts section so you can do
needed setup on the button:
</Attributes>
<Scripts>
11. Buttons, by default, are only registered for left-clicks when they’re created,
so you need to fix that if you want to right-click the button:
<OnLoad>
self:RegisterForClicks(“AnyUp“)
12. Because there is no action slot to which the button’s icon will be updated,
you need to set a static texture for its appearance:
_G[self:GetName()..“Icon“]:SetTexture(i
[[Interface\Icons\Spell_Holy_ImprovedResistanceAuras]])
13. The last step is close out the open tags and save the file:
</OnLoad>
</Scripts>
</Button>
</Ui>
Figure 15-2 shows the fully functional QuickCasterButton that you can use
to cast spells.
Figure 15-2: The functional QuickCasterButton
Understanding Taint and Working Safely Around
Secure Code
The secure code system depends on its function being very thorough. Any
attempt by insecure code to interfere with a secure action will cause the
secure action to fail or further spread the taint. Addons that approach or
manipulate secure buttons or other UI elements depend on a very close
association of secure and contagiously insecure code, and it’s easy to end up
getting the influence of insecure code where it doesn’t belong, causing familiar
elements of the UI to break in new and inventive ways.
Chapter 15 Taking Action with Secure Templates 303
If you’re getting error messages about actions only permitted to the Blizzard
UI, or ‘‘Interface action failed because of an AddOn’’ messages are cropping
up in your chat log, it’s important to understand how taint works and
spreads if you’re going to try and fix these issues. If you’re not familiar
with the protection violation error message, you can reproduce it by running
CastSpellByName(“Attack“) using WoWLua, producing the error shown in
Figure 15-3.
Figure 15-3: Protected function error
Notice that the message references WowLua. When WoW loads a Lua file,
every value created by the addon (functions and other globals) is marked as
such. In this case, the code in WowLua that executes your commands is known
to be tainted. When it tries to access CastSpellByName,theWoWgamecode
refuses to comply. Instead, it throws an error with the name of the addon that
caused the taint.
NOTE The CastSpellByName function itself is not blocked for tainted code.
Rather, it is the actual casting of spells that is blocked. For example, if you try to
cast a spell that you do not have, CastSpellByName will fail silently. Additionally,
you can safely use CastSpellByName to open tradeskills.
Enabling Taint Logging
Sometimes the way taint spreads can seem mysterious because of the various
and complex interactions of different parts of the UI code (addons, macros,
and built-in code). First, run the following command to turn on taint logging:
/console taintLog 1
The taint log shows you a time line of when taint occurs and how the taint
blocks an action. Level 1 only shows taint events if they lead up to a blocked
action. Level 2 records every single occurrence of taint including those that
are completely innocuous (and indeed inevitable). To turn off taint logging,
pass it a zero (0). The following is an example taint log attempting to run
CastSpellByName:
5/28 15:01:43.302 An action was blocked because of taint from WowLua -
CastSpellByName()
5/28 15:01:43.302 WowLua:1
5/28 15:01:43.302 pcall()
5/28 15:01:43.302 Interface\AddOns\WowLua\WowLua.lua:217 RunScript()
5/28 15:01:43.302 Interface\AddOns\WowLua\WowLua.lua:600 Button_Run()
304 Part III Advanced Addon Techniques
5/28 15:01:43.302 Interface\AddOns\WowLua\WowLua.lua:276 Button_OnClick()
5/28 15:01:43.302 WowLuaButton_Run:OnClick()
The first line shows the actual event, the call to CastSpellByName that
generated the error message shown in Figure 15-3. The other indented lines
show a stack trace leading up to the event to help you track down the source of
any problems. Upcoming sections take a closer look at some other taint logs.
Taint logs are saved as taint.log in the Logs folder of your WoW installation.
Like chat logs, they are only written to disk when the game exits or the UI
is reloaded. To see the taint log for your current session, you must manually
reload the UI and then open the file quickly because WoW sometimes likes to
emptyitduringgameplay.
Execution Taint
There are two ways to spread taint. One is temporary and only exists when
a particular chain of code is executing. The other is more persistent and the
cause of many headaches. The first is what you experienced in the preceding
example. The taint travels up the call stack from one function to another. For
example, enter the following command in the chat box (not WowLua):
/run WowLua:ProcessLine(“CastSpellByName(’Attack’)“)
WowLua works by reading each line of text you enter and then running it as
Lua code. With the preceding command, you are manually calling the function
that does this, telling it to attempt to cast the Attack spell. The important point
to note is that the game blames WowLua for the infraction, not the macro
command. Figure 15-4 illustrates the taint path and the state of the blame.
Error
/run ... Tainted as a
macro script
Tainted as
WowLua
Tainted as
WowLua
ProcessLine
CastSpellByName
Figure 15-4: Execution taint path
The taint begins when the macro processes the /run command (remember
that macros fall under the same restrictions as addons). At this point, the taint
is attributed to the macro command. If you were to call CastSpellByName
directly, the error would mention ‘‘A macro script.’’ Instead, you call
Chapter 15 Taking Action with Secure Templates 305
WowLua:ProcessLine, which now receives blame for the taint. The function
executes the code sent, which in turn tries to call CastSpellByName.Youcan
also follow this path through the taint log.
5/27 22:06:26.890 An action was blocked because of taint from WowLua -
CastSpellByName()
5/27 22:06:26.890 CastSpellByName(’Attack’):1
5/27 22:06:26.890 pcall()
5/27 22:06:26.890 Interface\AddOns\WowLua\WowLua.lua:177 ProcessLine()
5/27 22:06:26.890 WowLua:ProcessLine(“CastSpellByName(’Attack’)“):1
5/27 22:06:26.890 RunScript()
5/27 22:06:26.890 Interface\FrameXML\ChatFrame.lua:1826 ?()
5/27 22:06:26.890 Interface\FrameXML\ChatFrame.lua:3332 ChatEdit_ParseText()
5/27 22:06:26.890 Interface\FrameXML\ChatFrame.lua:3052 ChatEdit_SendText()
5/27 22:06:26.890 Interface\FrameXML\ChatFrame.lua:3073 i
ChatEdit_OnEnterPressed()
5/27 22:06:26.890 ChatFrameEditBox:OnEnterPressed()
Working from bottom to top, the log begins when you press Enter in the
chat box. Next, it works its way up to RunScript(), which applies the first
taint in the sequence, blaming it on ‘‘A macro script.’’ The macro script then
calls WowLua:ProcessLine, which receives blame for the taint.
Execution taint is transient because none of the functions involved is perma-
nently affected in any way. The default UI uses CastSpellByName for certain
cases of spell casting. Even after erroneously calling, as shown here, WoW
still behaves correctly. The taint itself goes away as soon as the original /run
command finishes.
Variable Taint
Less forgiving than execution taint, variable taint can permanently (for the
session) affect certain aspects of the built-in code. Variable taint is almost
an extension of execution taint; they both play off of each other, and even
overlap in some ways. Any tainted execution path has the potential to cause
variable taint.
Recall from Part I the ideas of values and references. World of Warcraft
has modified its Lua engine to store a taint flag with every value in the Lua
environment that identifies if the value is tainted, and the addon that caused
the taint. This is how the preceding example determined the blame. Variable
taint is caused when a tainted code path creates a new value or reference. Any
time your code makes a new global variable, function, table, and so on, that
new value is now tainted. Where you begin to run into trouble is when you
start modifying variables used by the default UI. Here’s an example in action.
Type the following line into WowLua:
/run NUM_ACTIONBAR_BUTTONS = NUM_ACTIONBAR_BUTTONS
306 Part III Advanced Addon Techniques
Now try to use any ability on your action bar and you will see an
addon blocked messages similar to the one you saw before. The func-
tion ActionButton_CalculateAction in FrameXML\ActionButton.lua uses this
variable to determine which action slot to activate when you press the button.
As soon as the code accesses the tainted value, the execution path becomes
infected with execution taint. This causes an error when the code attempts to
run the UseAction function. The only way to ‘‘cure’’ this condition is to reload
the UI.
NOTE The taint error from setting NUM_ACTIONBAR_BUTTONS will probably not
appear if you are using a custom bar mod. The default UI’s action buttons calculate
which action slot to use based on NUM_ACTIONBAR_BUTTONS, the button’s ID (set
via the id XML attribute), and some other pieces of data. Addons’ action buttons
usually do not use IDs, so ActionButton_CalculateAction never runs into the
tainted value.
NUM_ACTIONBAR_BUTTONS could be set to some number directly, but it is
important to realize that the taint is caused simply by the act of assignment
itself. The fact that the value came from a secure variable does not exempt you
from taint.
Another chart is helpful to picture the interactions. Figure 15-5 shows the
series of events that occurs when you click the action button after tainting
NUM_ACTIONBAR_BUTTONS. Again, note that it’s the simple action of reading the
tainted variable that causes the execution path to be tainted.
Error
OnClick Secure
Got WowLua’s taint by reading
NUM_ACTIONBAR_BUTTONS
Tainted as
WowLua
ActionButton_CalculateAction
UseAction
Figure 15-5: Code path tainted by a modified variable
Take a look at the resulting taint log:
5/28 15:27:23.454 Global variable NUM_ACTIONBAR_BUTTONS tainted by WowL
ua -
WowLua:1
5/28 15:27:23.454 pcall()
5/28 15:27:23.454 Interface\AddOns\WowLua\WowLua.lua:217 RunScript()
Chapter 15 Taking Action with Secure Templates 307
5/28 15:27:23.454 Interface\AddOns\WowLua\WowLua.lua:600 Button_Run()
5/28 15:27:23.454 Interface\AddOns\WowLua\WowLua.lua:276 Button_OnClick()
5/28 15:27:23.454 WowLuaButton_Run:OnClick()
5/28 15:27:23.454 Execution tainted by WowLua while reading i
NUM_ACTIONBAR_BUTTONS - Interface\FrameXML\ActionButton.lua:139 i
ActionButton_CalculateAction()
5/28 15:27:23.454 Interface\FrameXML\SecureTemplates.lua:253 handler()
5/28 15:27:23.454 Interface\FrameXML\SecureTemplates.lua:460
5/28 15:27:23.454 An action was blocked because of taint from WowLua -
UseAction()
5/28 15:27:23.454 Interface\FrameXML\SecureTemplates.lua:258 handler()
5/28 15:27:23.454 Interface\FrameXML\SecureTemplates.lua:460
The first ‘‘Global variable tainted’’ event shows the taint being applied
to NUM_ACTIONBAR_BUTTONS. The next ‘‘Execution tainted’’ event, which
was originally triggered by the button’s OnClick handler, occurs during
ActionButton_CalculateAction, as anticipated. Finally, UseAction is blocked
from executing because the code path was tainted.
NOTE This particular taint log illustrates a particular distinction between taint
log levels 1 and 2. Notice that all three events share the same time stamp. At level
1, WoW waits until taint actually causes a blocked action before reporting it. When
the action blocked message is generated, WoW goes back through its taint history
and retrieves the first two events, and all three events are then output to the log. If
you were to click the action button a second time, all three events would be
logged again, even though the first one happened some time ago.
On the other hand, level 2 records each event exactly as it happens. Every global
variable set by an addon generates a tainted message. Every time Blizzard code
reads an insecure variable, it generates an execution tainted message. This makes
level 2 extremely verbose, but it can also be more telling for a given issue.
Creeping Taint
One of the problems you may come across when dealing with taint issues
is the gradual spreading of variable taint. Say you have a tainted variable
used by the default UI (such as the earlier NUM_ACTIONBAR_BUTTONS example).
As explained, as soon as the built-in code accesses this variable, it becomes
tainted. Well, what happens when the tainted execution path then modifies
some other variable? That variable is now afflicted with the same taint that is
affecting the current execution path.
This process can happen repeatedly, often unnoticed, with each new tainted
variable potentially causing even more taint. In this way, your addon can taint
entire subsystems of the UI without modifying more than a single variable.
Not only can it spread far and wide, but the speed of the spreading can be
misleading. Some code in the default UI runs based on events that are not
308 Part III Advanced Addon Techniques
exactly frequent. One piece of misplaced taint may not cause any problems
until you join a raid group or travel to another continent, for example.
These situations are where the taint logs can really shine. When you receive
an ‘‘action blocked’’ message during development, simply turn on taint logging
and you can track down the problems. Level 2 is especially helpful in a case like
this because it allows you to see exactly when each variable becomes tainted.
Summary
This chapter covered a lot of ground. By now, you should be acquainted with:
The basic intent of the secure code system, which is to protect the game
from automation while still enabling customization.
The concept of protected frames and which of their characteristics are
restricted from changes during combat.
How frame attributes allow secure code to receive control messages safely
from addon code.
How taint can propagate from addon code to Blizzard code and cause the
UI to fail, and how to identify and prevent this.
The secure template system uses a wide assortment of specific features
taint, protected functions and frames, attributes, and so onto achieve a much
larger goal. It needs to protect the game against too much automation and, at
the same time, allow addons to alter the way you interact in combat. There is
still a lot to cover, but once you understand the basics laid out here, the rest
will flow much more freely.
CHAPTER
16
Binding Keys and Clicks
to Addon Code
Most of the user input discussed so far has revolved around the mouse
and graphical interface elements. Chapter 12 gave you a taste of OnClick,
OnEnter, and a few other handlers, as well as the Button and EditBox widgets.
In Chapter 15, you learned how to change the behavior of action buttons
depending on which mouse button was used and/or which modifier keys
were pressed at the time. This chapter shows you how to interact with the
keyboard and mouse directly, outside the context of UI widgets.
TIP The only forms of user input the WoW interface recognizes at the time of this
writing are keyboard and mouse. If you want to use alternative means to control
the game, say a gamepad or voice commands, you have to configure the hardware
or software so that they imitate a keyboard or mouse. There is evidence of
possible joystick or gamepad support in a future patch, but nothing is officially
part of the UI yet.
The key binding system treats both types of input the same way. Each key
or mouse button goes by a particular name. For basic letters, numbers, and
symbols, the name is simply the result of hitting the key with Caps Lock on.
Special keys and mouse buttons have descriptive names like LEFT,NUMPAD3,or
BUTTON1. For the sake of simplicity, we’ll refer to these as keys,whichyoucan
take to mean ‘‘key or mouse button name.’’ You use the key-binding interface
(accessible from the main game menu) as shown in Figure 16-1 to assign these
various keys to specific actions.
Keys and commands have a many-to-one relationship—you can bind many
keys to one command, but you can’t bind one key to many commands. You
309
310 Part III Advanced Addon Techniques
can see this in the screenshot, which has two columns of key buttons for each
command (behind the scenes, you’re not limited to two).
Figure 16-1: WoW key binding interface
The commands that appear in the default key binding interface are specified
in FrameXML\Bindings.xml.YoucanalsoprovideaBindings.xml file in the
root directory of your addon to add custom bindings to the list.
Defining Bindings in XML
The structure of Bindings.xml is very simple. The root element is Bindings,
and each command is represented by a single Binding element. The key
binding interface builds the list of bindings in the same order they appear in
the file. When addons provide a Bindings.xml, their bindings appear at the
end of the list in the order the addons are loaded. Take a look at an entry from
the default user interface:
<Bindings>
...
<Binding name=“TOGGLESHEATH“>
ToggleSheath();
Chapter 16 Binding Keys and Clicks to Addon Code 311
</Binding>
...
</Bindings>
The name attribute, in this case TOGGLESHEATH, sets the name of this particular
action. You use this name with the SetBinding() functions later in this
chapter. The key binding interface looks for a global string variable called
BINDING_NAME_name to label the binding in the list. For example, the value
of BINDING_NAME_TOGGLESHEATH is Sheath/Unsheath Weapon in the English
version of WoW (see Figure 16-1).
Once you bind a key to a command, the code inside the Binding tag
is executed whenever you press the key. In this case, because Zis bound
to TOGGLESHEATH, pressing Zcalls the ToggleSheath function, which cycles
through your equipped weapons.
NOTE There are certain situations in which key bindings might not appear to
work correctly, such as when you try to use a keyboard binding while an EditBox
widget has the keyboard focus. Similarly for mouse buttons, any time the cursor is
over a mouse-enabled frame, the frame consumes button clicks for use with
OnClick,OnMouseDown, and so on, whether or not the handlers have been
defined for the frame.
Key bindings are consulted only if the keys or buttons aren’t consumed by some
other aspect of the user interface.
Here’s another example from the built-in Bindings.xml that illustrates a
couple more features:
<Binding name=“MOVEANDSTEER“ runOnUp=“true“ header=“MOVEMENT“>
if ( keystate == “down“ ) then
MoveAndSteerStart();
else
MoveAndSteerStop();
end
</Binding>
As with the previous example, this binding includes a name attribute
and a Lua chunk. The new header attribute sets up a heading for the key
binding interface. In this case WoW looks for BINDING_HEADER_<attribute>
to determine the text of the header. You can see in Figure 16-1 that
BINDING_HEADER_MOVEMENT is defined as Movement Keys in the English client.
Of particular note is the runOnUp attribute, which tells the game to execute the
binding code twice: once when the key is pressed down, and again when
the key is released. The code sample shows that WoW provides a keystate
312 Part III Advanced Addon Techniques
parameter of either “down“ or “up“, allowing you to determine which condition
triggered the execution.
Creating Your Own Binding Actions
Now that you have an idea of the structure of the bindings file, take a moment
to experiment with some bindings of your own. For the next few sections,
you’ll work on an addon called BindingTest. Create a directory under your
AddOns directory called BindingTest.CreateBindingTest.toc and add the
following to the file:
## Interface: 30200
## Title: Key Bindings Test
## Notes: Demonstrates the usage of Bindings.xml
BindingTest.lua
BindingTest.xml
Create empty BindingTest.lua and BindingTest.xml files; you’ll add code
to them later. Finally, create a file called Bindings.xml and input the follow-
ing code:
<Bindings>
<Binding name=“BINDING_TEST1“ header=“BINDING_TEST“>
BindingTest_Test1()
</Binding>
<Binding name=“BINDING_TEST2“ runOnUp=“true“>
BindingTest_Test2(keystate)
</Binding>
</Bindings>
Notice that Bindings.xml is not listed in the table of contents fileWoW
always loads Bindings.xml if present.
If you start up WoW and open the key bindings interface, you should see
something like Figure 16-2.
Notice how there’s an empty space where the header will go, and how
your custom bindings are simply labeled with the action names from
Bindings.xml. To remedy this, open your addon’s Lua file and add the
following global strings:
BINDING_HEADER_BINDING_TEST = “Test bindings for Chapter 16“
BINDING_NAME_BINDING_TEST1 = “Test binding #1“
BINDING_NAME_BINDING_TEST2 = “Test binding #2“
Save the file and reload the user interface using the /reload slash command.
Now when you open the key bindings screen it should look like Figure 16-3.
Chapter 16 Binding Keys and Clicks to Addon Code 313
Figure 16-2: Key binding interface with blank test bindings
Figure 16-3: Key binding interface with named test bindings
314 Part III Advanced Addon Techniques
At this point, you can go ahead and bind keys to these two test bindings.
You’ll probably want to use keys that aren’t already bound to something
important to save you a bit of trouble when you get back to actually playing
the game. Because you haven’t defined the functions yet, activating the key
bindings triggers a Lua error. Add these functions to BindingTest.lua and
give them basic behavior as follows:
function BindingTest_Test1()
print(“Test binding #1 activated“)
end
function BindingTest_Test2(keystate)
if keystate == “down“ then
print(“Test binding #2 pressed“)
else
print(“Test binding #2 released“)
end
end
After reloading the UI, spend a few moments experimenting with the two
keys you bound. You’ll see results similar to Figure 16-4.
Figure 16-4: Sample output from key bindings
One point worth noting from this screenshot is that more than one binding
can be ‘‘in progress’’ simultaneously. This is illustrated in the last four lines
where Test #2 is pressed, then Test #1 is activated twice, and finally Test #2 is
released. The number of separate keys that you can use at the same time varies
depending on your keyboard hardware and operating system.
Binding Keys to Actions
The key binding interface works fairly well for basic binding control, but it
does have a few limitations. First off, many users complain about the interface
itself because it’s rather difficult to navigateespecially when you start piling
on more and more addons with their additional sections. There’s also the
problem mentioned earlier where only two keys are shown for a given action.
You may choose to bypass the default interface altogether for your addon,
or perhaps you want to make an addon that replaces the key binding interface
Chapter 16 Binding Keys and Clicks to Addon Code 315
itself with something a bit more flexible. Either way, you’ll need to set the key
bindings programmatically.
Building a Simple Binding UI
To give you an overview of the various binding APIs, create a basic binding
interface for the BindingTest addon. This interface will consist of two buttons,
one for each binding action. You left-click the buttons to add a binding
and right-click to remove a binding. Figure 16-5 shows an example of this
interface in use.
Figure 16-5: Basic key binding interface
To begin, open BindingTest.xml and add the following code:
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Button name=“BindingTestButtonTemplate“ inherits= i
“UIPanelButtonTemplate2“ virtual=“true“>
<Size x=“150“ y=“24“/>
<Scripts>
<OnLoad function=“BindingTestButton_OnLoad“/>
<OnClick function=“BindingTestButton_OnClick“/>
<OnEnter function=“BindingTestButton_OnEnter“/>
<OnLeave function=“BindingTestButton_OnLeave“/>
</Scripts>
</Button>
</Ui>
The two buttons will be identical in most respects, so you define a template
from which the buttons will inherit. The OnLoad script will initialize the button
with a label and associated binding information based on the button’s ID.
The OnClick script will display the bindings frame when clicked, and the
OnEnter/OnLeave scripts will show and hide the tooltip.
316 Part III Advanced Addon Techniques
Create a frame to hold the buttons and the buttons themselves by adding the
following code immediately after the template definition, within the Ui tag.
<Frame name=“BindingTestFrame“>
<Size x=“1“ y=“1“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Frames>
<Button name=“BindingTestButton1“ i
inherits=“BindingTestButtonTemplate“ id=“1“>
<Anchors>
<Anchor point=“BOTTOM“ relativePoint=“CENTER“/>
</Anchors>
</Button>
<Button name=“BindingTestButton2“ i
inherits=“BindingTestButtonTemplate“ id=“2“>
<Anchors>
<Anchor point=“TOP“ relativePoint=“CENTER“/>
</Anchors>
</Button>
</Frames>
</Frame>
The outer frame doesn’t really provide any functionality of its own; it
simply serves to encapsulate the two buttons. If you’d prefer not to have the
buttons directly in the center of the screen, you can anchor BindingTestFrame
elsewhere and the buttons will move with it.
The buttons themselves are anchored such that one sits directly above the
position of BindingTestFrame and the other sits just below.
Finally, you need a frame that can capture keyboard and mouse input so
you can assign the bindings as necessary. You’ll use a button widget to take
advantage of the OnClick handler. Start off by creating the basic appearance
of the button as follows:
<Button name=“BindingTestCaptureFrame“ hidden=“true“ enableKeyboard= i
“true“ frameStrata=“DIALOG“>
<Size x=“175“ y=“90“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Backdrop bgFile=“Interface\Tooltips\UI-Tooltip-Background“ edgeFile= i
“Interface\Tooltips\UI-Tooltip-Border“ tile=“true“>
Chapter 16 Binding Keys and Clicks to Addon Code 317
<EdgeSize val=“16“/>
<TileSize val=“16“/>
<BackgroundInsets left=“5“ right=“5“ top=“5“ bottom=“5“/>
<Color r=“0“ g=“0“ b=“0“/>
</Backdrop>
</Button>
Because this frame pops up in response to clicking one of the two buttons,
it starts off hidden. As soon as you show the frame it captures all key presses
thanks to the enableKeyboard attribute. The backdrop section gives the frame
an appearance similar to a tooltip. Next, add a font string immediately after
the </Backdrop> tag, but before the </Button> tag. This font string will be
used to display instructions to the user. Here’s the code:
<Layers>
<Layer level=“ARTWORK“>
<FontString inherits=“GameFontNormal“ parentKey=“text“>
<Anchors>
<Anchor point=“TOPLEFT“>
<Offset x=“10“ y=“-10“/>
</Anchor>
<Anchor point=“BOTTOMRIGHT“>
<Offset x=“-10“ y=“10“/>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
Finally, add the script definitions after the </Layers> tag:
<Scripts>
<OnLoad function=“BindingTestCapture_OnLoad“/>
<OnShow function=“BindingTestCapture_OnShow“/>
<OnKeyDown function=“BindingTestCapture_OnKeyDown“/>
<OnClick function=“BindingTestCapture_OnClick“/>
</Scripts>
The OnLoad script initializes the frame. The OnShow script changes the text
of the frame to indicate which binding is being changed. The OnKeyDown
and OnClick scripts are used to capture the keyboard and mouse input,
respectively.
Load the game at this point and you’ll see two blank buttons (see Figure 16-6)
in the middle of the screen that don’t do anything interesting when pressed.
318 Part III Advanced Addon Techniques
Figure 16-6: Blank binding test buttons
Defining Basic Behaviors
Now it’s time to add the behavior to your UI. Open the addon’s Lua file if it’s
not already open. After the global binding labels at the top of the file, add the
following strings:
local BUTTON_CAPTION = “Set Test Binding #%d“
local TOOLTIP_TEXT1 = “Left-click to add binding“
local TOOLTIP_TEXT2 = “Right-click to remove first binding“
local TOOLTIP_BINDING_LIST = “Currently bound: |cFFFFFFFF%s|r“
local LIST_SEPARATOR = “|r, |cFFFFFFFF“
local CAPTURE_TEXT = [[
Press a key or click this frame to set test binding #|cFFFFFFFF%d|r.
Press |cFFFFFFFFESC|r to cancel.]]
These strings are used as follows:
BUTTON_CAPTIONThis is the label for the two main buttons.
TOOLTIP_xxxx These are the text that appears in the tooltip.
LIST_SEPARATORThe ‘‘Currently bound’’ section of the tooltip lists each
key bound to the button’s associated action. This is the separator between
items in the list. Note the use of color codes to make the key names stand
out.
CAPTURE_TEXTThis is the text for the capture frame.
So you’ll be able to see the progress of your work at each step, create stubs
for all of the scripts you defined in the XML by adding the following code to
the end of the Lua file:
function BindingTestButton_OnLoad(self)
end
function BindingTestButton_OnClick(self, button)
end
function BindingTestButton_OnEnter(self)
end
Chapter 16 Binding Keys and Clicks to Addon Code 319
function BindingTestButton_OnLeave(self)
end
function BindingTestCapture_OnLoad(self)
end
function BindingTestCapture_OnShow(self)
end
function BindingTestCapture_OnKeyDown(self, key)
end
function BindingTestCapture_OnClick(self, button)
end
Start off the addon’s behavior by filling in the Button_OnLoad function
as follows:
function BindingTestButton_OnLoad(self)
local id = self:GetID()
self:SetText(BUTTON_CAPTION:format(id))
self.action = “BINDING_TEST“..id
self:RegisterForClicks(“LeftButtonUp“, “RightButtonUp“)
end
First the function sets the text of the button based on the button’s ID. Next it
stores the name of the associated binding action. Finally, it registers the button
to receive left- and right-clicks. Reload your UI and the buttons should now
look like Figure 16-7.
Figure 16-7: Binding test buttons with labels
Of course, the labels bear false witness because the buttons don’t actually
do anything yet. Fix that by filling in the Button_OnClick function:
function BindingTestButton_OnClick(self, button)
if button == “LeftButton“ then
BindingTestCaptureFrame.button = self
320 Part III Advanced Addon Techniques
BindingTestCaptureFrame:Show()
elseif button == “RightButton“ then
-- Binding removal code will go here
end
end
As you can see, a left-click shows the capture frame after initializing it with
the selected button. For now, the right-click behavior is empty. You’ll fill that
in later after working with some of the binding APIs.
Before reloading the UI, you’ll want to make sure there’s a way to close
the capture frame. Because it captures all keyboard input, you won’t be
able to use any other key bindings until it’s hidden. This means you
won’t be able to bring up the chat box to type /run ReloadUI() or /run
BindingTestCaptureFrame:Hide(). At best, you can click the game menu
button and log out. To prevent this difficulty, add a check for the Escape key
to Capture_OnKeyDown:
function BindingTestCapture_OnKeyDown(self, key)
if key == “ESCAPE“ then
self:Hide()
return
end
end
Reload the UI and your buttons will now bring up a blank capture frame as
shown in Figure 16-8.
TIP If you ever find yourself stuck with a keyboard capturing frame and can’t
access the main menu or don’t want to log out completely, you can use a few
tricks to bring up the chat box.
First, check your chat log. If you have any messages from anyone in any channel,
you can click their name to begin a whisper. Similarly, if there are any friendly
characters nearby, you can target them and right-click their portrait to start a
whisper. You can also find whisper targets by bringing up the Who window. Once
you’ve initiated a whisper, you can use the edit box to type any slash command.
Figure 16-8: Blank binding test capture frame
Chapter 16 Binding Keys and Clicks to Addon Code 321
You have just a couple more clerical matters to attend to before moving
on to the binding functions. Fill in the Capture_OnLoad and Capture_OnShow
functions as follows:
function BindingTestCapture_OnLoad(self)
self:RegisterForClicks(“AnyUp“)
end
function BindingTestCapture_OnShow(self)
self.text:SetText(CAPTURE_TEXT:format(self.button:GetID()))
end
Now the frame is prepared to respond to any mouse click and also displays
instructions for setting the binding as shown in Figure 16-9.
Figure 16-9: Final binding test capture frame
Using SetBinding()
With the housekeeping tasks out of the way, you can now concentrate on
the bindings themselves. The heart of the binding API is the SetBinding()
function, which associates a key with a binding action:
success = SetBinding(“key“[, “action“])
The key parameter is a string representing the desired key press (for example,
SHIFT-F5)andtheaction parameter is the name of the binding action you
want the key to trigger. If the action is omitted (or nil for clarity) the binding is
removed from the key. SetBinding() returns 1or nil depending on whether
the binding was successfully set.
The capture frame knows what action to use by looking at its button
field, which was set by BindingTestButton_OnClick.Sothemainjobof
BindingTestCapture_OnKeyDown is to build the key parameter and call
SetBinding().Now,OnKeyDown captures every key individually, even
modifier keys. Because you can’t bind modifier keys, you should ignore them
by adding the following code to the end of the OnKeyDown function:
local modifier = key:sub(2)
if modifier == “SHIFT“ or
322 Part III Advanced Addon Techniques
modifier == “CTRL“ or
modifier == “ALT“ or
key == “UNKNOWN“ then
return
end
When OnKeyDown receives a modifier key, it differentiates between keys on
the left and right sides of the keyboard. For example, the left shift key is called
LSHIFT and the right shift key is called RSHIFT. The first line in the preceding
snippet eliminates a bit of redundancy in the if clause by stripping the first
character off the key. You also check for UNKNOWN, which is triggered by keys
that WoW doesn’t recognize (like Scroll Lock and Pause on Windows).
You should also add special treatment for the key normally used to take
screenshots. Otherwise there would be no way to take a screenshot of the
binding. Add the following code immediately after the previous snippet:
if GetBindingFromClick(key) == “SCREENSHOT“ then
TakeScreenshot()
return
end
The function GetBindingFromClick, defined in FrameXML\UIParent.lua,
returns the action associated with the current key press, if any. If the action
turns out to be SCREENSHOT, this code takes a screenshot and aborts the function.
Once you’ve eliminated the special cases, you can begin building the
key argument. Although you ignored the modifier keys when they directly
triggered OnKeyDown, you need to check their status to apply the appropriate
prefixes to the key. Add this code following the screenshot check:
if IsShiftKeyDown() then
key = “SHIFT-“..key
end
if IsControlKeyDown() then
key = “CTRL-“..key
end
if IsAltKeyDown() then
key = “ALT-“..key
end
Note that the order of these modifier checks is crucial; SetBinding only
accepts modifier prefixes in the order ALT-CTRL-SHIFT-. In this snippet,
you’re adding them one at a time, as applicable, to the beginning of the
key. If you pressed A with all the modifier keys held down, the key parameter
would progress as follows:
A
SHIFT-A
Chapter 16 Binding Keys and Clicks to Addon Code 323
CTRL-SHIFT-A
ALT-CTRL-SHIFT-A
Now that you have the key argument built, you can call SetBinding() and
close the capture frame. Add these final two lines to the OnKeyDown function:
SetBinding(key, self.button.action)
self:Hide()
This code actually calls the binding API and then hides the binding UI.
At this point, the addon does most of what it advertises. If you press one
of the buttons, it brings up the capture frame. Then when you press a key
combination, it sets the binding and hides the capture frame. You should be
able to see the new bindings in the WoW key binding UI, unless you already
had two bindings in place. Even then your binding is still there but the UI isn’t
designed to show more than two. This addon won’t be so limited. Later you
add functionality to the tooltips that lists all keys bound to the given action.
NOTE If you test out the addon, you may notice that the key bindings don’t
survive through a UI reload. SetBinding on its own doesn’t commit any changes
to the server. You can use this to your advantage because you don’t have to be as
careful about overwriting your existing bindings. However, if you open up the
built-in key binding UI, clicking Okay saves the bindings you created with this
addon. Be sure to hit Cancel instead if you don’t want to save the changes (it will
also revert the changes you did make). You learn more about binding storage in a
later section.
Earlier we mentioned that the key binding API treats mouse clicks and
button clicks in the same way. This means the OnClick handler can simply
call OnKeyDown with the appropriate mouse button name. Unfortunately, the
names used for mouse click handlers aren’t the same as what the binding APIs
expect, as shown in Table 16-1.
This translation is extremely simple thanks to Lua’s tables. Immediately
before the definition of BindingTestCapture_OnClick, add the following code:
local buttonKeys = {
[“MiddleButton“] = “BUTTON3“,
[“Button4“] = “BUTTON4“,
[“Button5“] = “BUTTON5“
}
NOTE You are omitting LeftButton and RightButton because those mouse
buttons have such crucial roles in gameplay that it’s usually a bad idea to remove
their bindings. Otherwise you’d be unable to target units in the game world, turn
the camera, or interact with objects such as doors, chests, NPCs, corpses, and so
324 Part III Advanced Addon Techniques
on. It’s possible to bind their actions (CAMERAORSELECTORMOVE and
TURNORACTION, respectively) to other keys, but you still have to position the
mouse cursor over the object with which you’re trying to interact.
As an exercise, you might consider allowing re-binding of the left and right mouse
buttons. After the binding is made, leave the capture window open and ask for a
new key for the appropriate action.
Table 16-1: Mouse Clicks and Their Corresponding Binding Keys
MOUSE CLICK BINDING KEY
LeftButton BUTTON1
RightButton BUTTON2
MiddleButton BUTTON3
Button4 BUTTON4
Button5 BUTTON5
Now all you need to do is make sure the clicked button is in the table and
pass it to OnKeyDown. Fill in BindingTestCapture_OnClick as follows:
function BindingTestCapture_OnClick(self, button)
local key = buttonKeys[button]
if not key then
return
end
BindingTestCapture_OnKeyDown(self, key)
end
And with that, your test addon can now capture all the bindings it was
designed to handle.
Working with Existing Bindings
Now that you can add all the bindings you want, it would be help-
ful to implement binding removal. We left a place for this code inside
BindingTestButton_OnClick earlier in the chapter. Edit that function so it
looks like this:
function BindingTestButton_OnClick(self, button)
if button == “LeftButton“ then
BindingTestCaptureFrame.button = self
BindingTestCaptureFrame:Show()
Chapter 16 Binding Keys and Clicks to Addon Code 325
elseif button == “RightButton“ then
local key = GetBindingKey(self.command)
if key then
SetBinding(key, nil)
end
BindingTestButton_OnEnter(self)
end
end
The GetBindingKey API function accepts the name of a command and
returns a list of all the keys bound to the action. For this simple interface,
you’re only interested in the first one. The code checks to see if there’s a
binding for the button’s command and if so, clears it. The last line in the
new code triggers OnEnter to refresh the tooltip, which you will imple-
ment next.
Displaying an Action’s Bindings
As mentioned earlier, the tooltip explains how to use the binding buttons and
shows a list of all keys currently bound to the button’s action. Tooltips are
covered in depth in Chapter 24, but the usage here should be simple enough
to understand. To start, create and show the tooltip when the mouse enters
the button. Add the following code to BindingTestButton_OnEnter:
GameTooltip:SetOwner(self, “ANCHOR_BOTTOMRIGHT“)
GameTooltip:AddLine(TOOLTIP_TEXT1)
GameTooltip:AddLine(TOOLTIP_TEXT2)
The first line clears the tooltip and anchors it to the bottom-right corner of
the button. The next two lines add the basic left- and right-click instructions.
Next, build the list of keys with the following code:
local list = {GetBindingKey(self.command)}
for i, key in ipairs(list) do
list[i] = GetBindingText(key, “KEY_“)
end
Here you’re using GetBindingKey again, but this time you store all the results
in a table. Then you use GetBindingText (defined in FrameXML\UIParent.lua)
to translate the key names into more human-readable forms. For instance,
BUTTON3 becomes Middle Mouse. Finish up this function as follows:
GameTooltip:AddLine(
TOOLTIP_BINDING_LIST:format(table.concat(list, LIST_SEPARATOR)),
NORMAL_FONT_COLOR.r,
NORMAL_FONT_COLOR.g,
NORMAL_FONT_COLOR.b,
326 Part III Advanced Addon Techniques
1
)
GameTooltip:Show()
The first argument to GameTooltip:AddLine is built by joining all the key
names together with LIST_SEPARATOR between them, and then formatting this
into the TOOLTIP_BINDING_LIST string. Because the list can potentially grow
pretty long, the last argument of 1tells the tooltip to wrap the text of this line.
AddLine has optional color parameters positioned before the wrap flag, so you
need to provide arguments to avoid unintended effects.
TIP You can find global constants for WoW’s standard text colors in
FrameXML\FontStyles.xml.
AsImsureyouveguessed,thelastlineoftheprecedingcodeshowsthe
tooltip. Now fill in BindingTestButton_OnLeave as follows to hide the tooltip
after the mouse leaves the button:
function BindingTestButton_OnLeave(self)
GameTooltip:Hide()
end
This addon now has all of its promised functionality. If you test it now you
should be able to see results similar to Figure 16-5.
Understanding Binding Storage
Manipulating bindings is all well and good, but it doesn’t help much if
the changes are only temporary. In this section you explore how to save the
changes you make.
You can save bindings in two different ways: account-wide or char-
acter-specific. Normally the player will choose which one to use via the
checkbox at the top of WoW’s key binding interface. To find out which set
is currently active you use the function GetCurrentBindingSet.Thisfunction
returns 1for account-wide and 2for character-specific bindings. Once you’ve
determined which set you want to save, you simply call SaveBindings and the
deed is done.
To make the binding test addon save its changes, simply add the following
line after each of the calls to SetBinding in BindingTestButton_OnClick and
BindingTestCapture_OnKeyDown:
SaveBindings(GetCurrentBindingSet())
Chapter 16 Binding Keys and Clicks to Addon Code 327
In a more comprehensive binding interface you would need a way to undo
the changes you make with SetBinding. WoW’s key binding interface does
this when you hit Cancel. You could add a Save button that delays the saving
of bindings until it’s clicked, and then you can ‘‘restore’’ the saved bindings
by simply loading them:
LoadBindings(GetCurrentBindingSet())
Binding Keys to Secure Actions
For addons, basic binding commands like you’ve dealt with so far are only
useful for actions unrelated to combat. They’re fine for things like displaying
a configuration window, reloading the UI, opening a chat window, and so
on. But as you learned in Chapter 15, your Lua code isn’t allowed to directly
trigger actions resulting in ability/item use or target selection. Because of this
limitation, there is a set of APIs much like SetBinding that can trigger various
secure actions:
success = SetBindingSpell(“key“[, “spellname“])—Binds the key
directly to a spell. Be sure the name you provide conforms to the
requirements of CastSpellByName.
success = SetBindingItem(“key“[, “itemname“ or “itemlink“])
Binds the key to use the given item.
success = SetBindingMacro(“key“[, macroid or “macroname“])
Binds to the specified macro. The macro parameters should match the
expectations of RunMacro.
success = SetBindingClick(“key“[, “framename“[, “button“]])
Click bindings act as if the key press were a mouse click on the specified
frame. The button parameter is passed to the frame’s various mouse
handlers as the name of the mouse button. If you omit this parameter, it
defaults to LeftButton.
As with SetBinding, if you provide a key argument but no others, the
binding is removed from that key.
The first two are pretty self-explanatory. Although they’re limited in scope,
they prove useful in many situations. SetBindingMacro is a bit more flexible
because macros can perform decision making, take multiple actions, and so
on. However, because macros are highly user-specific and there’s limited
storage, you should use this only if the point of your addon is to interact with
the user’s own macros. If you need a binding to trigger your own complex
behavior, you should implement that behavior in a secure button and use
SetBindingClick.
328 Part III Advanced Addon Techniques
Working with Click Bindings
To give you an idea of how click bindings work, run the following script in
WowLua or put it into a new addon:
local testButton = CreateFrame(“Button“, “ClickBindingTestButton“)
testButton:RegisterForClicks(“AnyUp“, “AnyDown“)
testButton:SetScript(“OnMouseDown“, function(self, button)
print(“OnMouseDown:“, button)
end)
testButton:SetScript(“OnMouseUp“, function(self, button)
print(“OnMouseUp:“, button)
end)
testButton:SetScript(“PreClick“, function(self, button, down)
print(“PreClick:“, button, (down and “Down“ or “Up“))
end)
testButton:SetScript(“OnClick“, function(self, button, down)
print(“OnClick:“, button, (down and “Down“ or “Up“))
end)
testButton:SetScript(“PostClick“, function(self, button, down)
print(“PostClick:“, button, (down and “Down“ or “Up“))
end)
Using either WowLua or a /run command, bind some keys to the button
like the following:
SetBindingClick(“A“, “ClickBindingTestButton“)
SetBindingClick(“B“, “ClickBindingTestButton“, “Zebra“)
If you press and release B at this point, you should see the following output:
OnMouseDown: Zebra
PreClick: Zebra Down
OnClick: Zebra Down
PostClick: Zebra Down
OnMouseUp: Zebra
PreClick: Zebra Up
OnClick: Zebra Up
PostClick: Zebra Up
As you can see, the binding goes through all the motions that would
normally be associated with a real mouse click. In fact, in an early Burning
Crusade beta when these functions were first implemented, moving the mouse
while holding down a key bound to an action button would drag the ability
off the button!
Chapter 16 Binding Keys and Clicks to Addon Code 329
Creating Secure Bindings in XML
One problem you may have noticed with these specialized binding func-
tions is that there’s no representation in the key binding UI. Luckily these
four functions are simply conveniences. Each one is equivalent to calling
SetBinding with a specially built action of one of these forms:
SPELL spellName
ITEM itemNameOrLink
MACRO macroNameOrID
CLICK frameName:mouseButton
For example, the earlier SetBindingClick examples would translate to:
SetBinding(“A“, “CLICK ClickBindingTestButton:LeftButton“)
SetBinding(“B“, “CLICK ClickBindingTestButton:Zebra“)
You can use these new actions in Bindings.xml so that they appear in
WoW’s UI. The two example bindings would look like the following:
<Binding name=“CLICK ClickBindingTestButton:LeftButton“ runOnUp=“true“/>
<Binding name=“CLICK ClickBindingTestButton:Zebra“ runOnUp=“true“/>
Creating the labels for these bindings takes a bit of trickery because variables
can’t have spaces in their names. However, these are global variables, so you
can use any string as an index to the global environment. One way to do this
by setting the key directly in the _G table:
_G[“BINDING_NAME_CLICK ClickBindingTestButton:LeftButton“] = i
“ClickBindingTest LeftButton“
_G[“BINDING_NAME_CLICK ClickBindingTestButton:Zebra“] = i
“ClickBindingTest Zebra“
These bindings would now appear in the key binding interface with their
human-readable labels.
Summary
This chapter has provided you with all the tools you need for day-to-day
key binding tasks, from integrating with the built-in binding UI to setting
bindings programmatically. You have also seen some techniques useful for
330 Part III Advanced Addon Techniques
building your own binding UIs or perhaps even creating a dedicated addon
to improve on WoW’s binding interface.
The next chapter shows how to create slash commands for your addons,
adding to the functionality you’ve already created.
The Code
BindingTest
BindingTest.toc
## Interface: 30200
## Title: Binding Test
## Notes: Demonstrates the usage of Bindings.xml
BindingTest.lua
BindingTest.xml
BindingTest.xml
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Button name=“BindingTestButtonTemplate“ inherits=
“UIPanelButtonTemplate2“ virtual=“true“>
<Size x=“150“ y=“24“/>
<Scripts>
<OnLoad function=“BindingTestButton_OnLoad“/>
<OnClick function=“BindingTestButton_OnClick“/>
<OnEnter function=“BindingTestButton_OnEnter“/>
<OnLeave function=“BindingTestButton_OnLeave“/>
</Scripts>
</Button>
<Frame name=“BindingTestFrame“>
<Size x=“1“ y=“1“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Frames>
<Button name=“BindingTestButton1“
inherits=“BindingTestButtonTemplate“
id=“1“>
Chapter 16 Binding Keys and Clicks to Addon Code 331
<Anchors>
<Anchor point=“BOTTOM“ relativePoint=“CENTER“/>
</Anchors>
</Button>
<Button name=“BindingTestButton2“
inherits=“BindingTestButtonTemplate“
id=“2“>
<Anchors>
<Anchor point=“TOP“ relativePoint=“CENTER“/>
</Anchors>
</Button>
</Frames>
</Frame>
<Button name=“BindingTestCaptureFrame“ hidden=“true“ i
enableKeyboard=“true“ frameStrata=“DIALOG“>
<Size x=“175“ y=“90“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Backdrop bgFile=“Interface\Tooltips\UI-Tooltip-Background“ i
edgeFile=“Interface\Tooltips\UI-Tooltip-Border“ tile=“true“>
<EdgeSize val=“16“/>
<TileSize val=“16“/>
<BackgroundInsets left=“5“ right=“5“ top=“5“ bottom=“5“/>
<Color r=“0“ g=“0“ b=“0“/>
</Backdrop>
<Layers>
<Layer level=“ARTWORK“>
<FontString inherits=“GameFontNormal“ parentKey=“text“>
<Anchors>
<Anchor point=“TOPLEFT“>
<Offset x=“10“ y=“-10“/>
</Anchor>
<Anchor point=“BOTTOMRIGHT“>
<Offset x=“-10“ y=“10“/>
</Anchor>
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad function=“BindingTestCapture_OnLoad“/>
<OnShow function=“BindingTestCapture_OnShow“/>
<OnKeyDown function=“BindingTestCapture_OnKeyDown“/>
<OnClick function=“BindingTestCapture_OnClick“/>
</Scripts>
</Button>
</Ui>
332 Part III Advanced Addon Techniques
BindingTest.lua
BINDING_HEADER_BINDING_TEST = “Test bindings for Chapter 16“
BINDING_NAME_BINDING_TEST1 = “Test binding #1“
BINDING_NAME_BINDING_TEST2 = “Test binding #2“
local BUTTON_CAPTION = “Set Test Binding #%d“
local TOOLTIP_TEXT1 = “Left-click to add binding“
local TOOLTIP_TEXT2 = “Right-click to remove first binding“
local TOOLTIP_BINDING_LIST = “Currently bound: |cFFFFFFFF%s|r“
local LIST_SEPARATOR = “|r, |cFFFFFFFF“
local CAPTURE_TEXT = [[
Press a key or click this frame to set test binding #|cFFFFFFFF%d|r.
Press |cFFFFFFFFESC|r to cancel.]]
function BindingTest_Test1()
print(“Test binding #1 activated“)
end
function BindingTest_Test2(keystate)
if keystate == “down“ then
print(“Test binding #2 pressed“)
else
print(“Test binding #2 released“)
end
end
function BindingTestButton_OnLoad(self)
local id = self:GetID()
self:SetText(BUTTON_CAPTION:format(id))
self.action = “BINDING_TEST“..id
self:RegisterForClicks(“LeftButtonUp“, “RightButtonUp“)
end
function BindingTestButton_OnClick(self, button)
if button == “LeftButton“ then
BindingTestCaptureFrame.button = self
BindingTestCaptureFrame:Show()
elseif button == “RightButton“ then
local key = GetBindingKey(self.action)
if key then
SetBinding(key, nil)
SaveBindings(GetCurrentBindingSet())
end
BindingTestButton_OnEnter(self)
end
end
function BindingTestButton_OnEnter(self)
GameTooltip:SetOwner(self, “ANCHOR_BOTTOMRIGHT“)
Chapter 16 Binding Keys and Clicks to Addon Code 333
GameTooltip:AddLine(TOOLTIP_TEXT1)
GameTooltip:AddLine(TOOLTIP_TEXT2)
local list = {GetBindingKey(self.action)}
for i, key in ipairs(list) do
list[i] = GetBindingText(key, “KEY_“)
end
GameTooltip:AddLine(
TOOLTIP_BINDING_LIST:format(table.concat(list, LIST_SEPARATOR)),
NORMAL_FONT_COLOR.r,
NORMAL_FONT_COLOR.g,
NORMAL_FONT_COLOR.b,
1
)
GameTooltip:Show()
end
function BindingTestButton_OnLeave(self)
GameTooltip:Hide()
end
function BindingTestCapture_OnLoad(self)
self:RegisterForClicks(“AnyUp“)
end
function BindingTestCapture_OnShow(self)
self.text:SetText(CAPTURE_TEXT:format(self.button:GetID()))
end
function BindingTestCapture_OnKeyDown(self, key)
if key == “ESCAPE“ then
self:Hide()
return
end
local modifier = key:sub(2)
if modifier == “SHIFT“
or modifier == “CTRL“
or modifier == “ALT“
or key == “UNKNOWN“ then
return
end
if GetBindingFromClick(key) == “SCREENSHOT“ then
TakeScreenshot()
return
end
334 Part III Advanced Addon Techniques
if IsShiftKeyDown() then
key = “SHIFT-“..key
end
if IsControlKeyDown() then
key = “CTRL-“..key
end
if IsAltKeyDown() then
key = “ALT-“..key
end
SetBinding(key, self.button.action)
SaveBindings(GetCurrentBindingSet())
self:Hide()
end
local buttonKeys = {
[“MiddleButton“] = “BUTTON3“,
[“Button4“] = “BUTTON4“,
[“Button5“] = “BUTTON5“
}
function BindingTestCapture_OnClick(self, button)
local key = buttonKeys[button]
if not key then
return
end
BindingTestCapture_OnKeyDown(self, key)
end
Bindings.xml
<Bindings>
<Binding name=“BINDING_TEST1“ header=“BINDING_TEST“>
BindingTest_Test1()
</Binding>
<Binding name=“BINDING_TEST2“ runOnUp=“true“>
BindingTest_Test2(keystate)
</Binding>
</Bindings>
ClickBindingTest
ClickBindingTest.toc
## Interface: 30200
## Title: Click Binding Test
## Notes: Demonstrates the use of click bindings
ClickBindingTest.lua
Chapter 16 Binding Keys and Clicks to Addon Code 335
ClickBindingTest.lua
local testButton = CreateFrame(“Button“, “ClickBindingTestButton“)
testButton:RegisterForClicks(“AnyUp“, “AnyDown“)
testButton:SetScript(“OnMouseDown“, function(self, button)
print(“OnMouseDown:“, button)
end)
testButton:SetScript(“OnMouseUp“, function(self, button)
print(“OnMouseUp:“, button)
end)
testButton:SetScript(“PreClick“, function(self, button, down)
print(“PreClick:“, button, (down and “Down“ or “Up“))
end)
testButton:SetScript(“OnClick“, function(self, button, down)
print(“OnClick:“, button, (down and “Down“ or “Up“))
end)
testButton:SetScript(“PostClick“, function(self, button, down)
print(“PostClick:“, button, (down and “Down“ or “Up“))
end)
CHAPTER
17
Creating Slash Commands
World of Warcraft players interact daily with slash commands. Whether it’s
/ignore Ikeelyou or a hasty /gquit after ninja looting Kael’thas on your
guild’s first takedown, you’re using slash commands.
As an addon author, you’ll often find it easier or just plain useful to have
slash commands to either spur your addon to action or to enable configuration.
Generally speaking, it’s much quicker to write out a quick slash command
system than to have a fully functioning graphical configuration screen.
Creating Basic Slash Commands
WoW provides a fairly straightforward way to implement slash commands.
They require two basic components: a set of global variables for the com-
mands and a handler function in a global table. Here is a quick example:
SLASH_FANCYPRINT1 = “/fancyprint“
SlashCmdList[“FANCYPRINT“] = function(msg)
print(“|cff11ff11“ .. Printed:|r “ .. msg)
end
Once you’ve run that code, type the following in the chat frame’s edit box:
/fancyprint This is my first slash command!
You should see a message printed to the chat frame that says, ‘‘This is my
first slash command!’’, after a green heading that says ‘‘Printed’’.
Now take a look at the process that made this possible. WoW stores all the
slash command handlers in a table called SlashCmdList. The table is indexed
337
338 Part III Advanced Addon Techniques
by arbitrary strings determined by the addon author. These indexes are used
to construct global variable names of the following format:
SLASH_INDEXn
In the previous example, the index is FANCYPRINT and the global variable is
SLASH_FANCYPRINT1. When you ran the slash command, WoW started looking
through all the entries in SlashCmdList. For each entry in the list, the system
started counting up from 1 and looked at the constructed global variables that
might match. As soon as it looked at SLASH_MESSAGE1 and saw the match, it
ran the associated function from SlashCmdList, passing all of the text provided
to the command.
This arrangement allows for great flexibility. Type SLASH_FANCYPRINT2 =
“/fp“ in WowLua and then try using that slash command with /fp I created
a slash command alias. Again you should see a message pop up with
those words.
As you just saw, incrementing the number in the global variable allows for
multiple slash commands to be aliased to the same handler. This also comes
in handy for localization.
So just to recap, here’s a checklist for creating slash commands:
Create a handler function that takes a single string parameter.
Pick a unique index name (ideally something that contains the addon’s
name, to avoid collisions) and add the function to SlashCmdList.
Create one or more global variables named SLASH_INDEXn containing the
slash commands.
As you can see, creating slash commands is the easy part. Getting them to do
anything less trivial than the preceding example is another story. Remember
that anything the user types in after the slash command is passed as a single
string to the handler. To do anything useful with it, you’ll have to do some
basic string parsing. The rest of this chapter focuses on a few simple techniques.
WARNING The slash command system keeps a cache of the commands you use
during a session, which reduces the impact of macros on game performance. It
also means that if you try to overwrite a SlashCmdList entry without reloading
the UI you need to update the cache. For example, if you use the slash command
you created in WowLua, then make a change to the code and execute the script,
WoW will try to use the original function the next time you run the command.
You can run the following code manually or add it to the end of your script:
wipe(hash_SlashCmdList)
Chapter 17 Creating Slash Commands 339
This is necessary only if you are making a change to a slash command handler that
you have already defined. It is not necessary when you’re first creating your new
command.
The details of the cache are beyond the scope of this chapter, but the general
technique is described in Appendix A. You can also see the command handling
code for yourself in FrameXML\ChatFrame.lua.
Tokenizing Strings
Tokenization is the process of dividing a string into smaller pieces called tokens
based on certain rules. One of the simplest ways to accomplish this is with
the WoW-specific function string.split (or strsplit). This function splits a
string at occurrences of given delimiters. For example:
string.split(“ “, “1 + 3 * 5“)
This splits the given string at every space (the delimiter), returning the
tokens “1“,“+“,“3“,“*“,and“5“.
As the example hints, you can create a simple calculator using this technique.
Create a new addon with just a Lua file or open up WowLua. To keep
the calculator simple, it will recognize only four operators: addition (+),
subtraction (), multiplication (*), and division (/). Furthermore, there will be
no order of precedence of operations. In other words, 1 +3*5=20, not 16.
The operations themselves are contained in a table indexed by the operator.
Enter the following code into WowLua or the new addon you created:
local operators = {
[“+“] = function(a, b)
return a + b
end,
[“-“] = function(a, b)
return a - b
end,
[“*“] = function(a, b)
return a * b
end,
[“/“] = function(a, b)
return a / b
end
}
Each operator simply accepts two numbers and returns the result of the
operation. Because all the operations proceed in order of occurrence, your main
340 Part III Advanced Addon Techniques
calculation function can simply iterate through the returns of string.split as
follows:
local function calculate(number1, ...)
for i = 1, select(“#“, ...), 2 do
local operator, number2 = select(i, ...)
number1 = operators[operator](number1, number2)
end
return number1
end
The first number is placed into the variable number1. The loop begins by
retrieving the first operator and the second number. Then it calls the appro-
priate operator function with the two given numbers and assigns the new value
to number1. Each time through the loop it picks a new operator and second
number, and performs the calculation. Once it passes the last parameter, the
function returns the final value of number1.
Now all that’s left is to create the slash command to split the message and
print the result of the calculation:
SLASH_SIMPLECALC1 = “/calculate“
SLASH_SIMPLECALC2 = “/calc“
SlashCmdList[“SIMPLECALC“] = function(message)
print(calculate(string.split(“ “, message)))
end
Run the script or load the addon and you should be able to use the slash
commands as expected. Here are some examples:
/calculate 1 + 3 * 5
20
/calc3*2+4/5.5
1.8181818181818
/calc 4
4
Obviously this is functional, but it has a couple of pitfalls. Because the string
is split at every occurrence of the space character, it’s as if there is an empty
string between any two consecutive spaces. For example:
/calculate 3 + 4
Error: attempt to call field '?' (a nil value)
With the extra space between the 3and the +, the string is split into the
tokens “3“,““,“+“,“4“. This means the calculate function tries to use ““
Chapter 17 Creating Slash Commands 341
as an index to the operators table, which is obviously an error. A similar
problem occurs if you omit a space:
/calc 3+4 * 5
Error: attempt to perform arithmetic on local 'a' (a string value)
Here the string is tokenized into “3+4“,“*“,and“5“.Thecalculate function
tries to call the multiplication operator with “3+4“ as one of the numbers, again
an obvious error.
Although these drawbacks affect the usability of this calculator addon,
splitting on spaces is still sufficient for many purposes. Later in this chapter
you’ll use this technique again but in a much more powerful way. For now,
let’s relax the syntax for the calculator addon.
Tokenizing with Patterns
Parsing strings is a topic that can fill a volume in its own right. Many different
techniques exist depending on the complexity of your rules. Entire computer
languages have been designed specifically to describe the syntax of other lan-
guages. Although a full treatment is obviously beyond the scope of this book,
we can at least show you some of the tricks Lua brings to the table.
Chapter 6 provided a glimpse of Lua patterns that enable you to look for
specific arrangements of characters within a string. Now you’ll use them to
identify individual components of the calculator commands.
Setting Up the Patterns
First you should put the syntax of the commands into more definite terms.
The format for these commands is as follows:
number [operator number [operator number [ ... ] ]
This gives you the overall structure you need to follow when parsing the
string. Later you design the parsing functions to follow this general pattern.
Next you need to break down the format of each component. Operators are
simply one of the four operator characters. Numbers are a bit more complex:
[sign][digits][decimal]digits
From here, you can easily construct the patterns for each component. To
keep the code flexible, you won’t use a specialized pattern for the operators.
342 Part III Advanced Addon Techniques
Instead you’ll simply match any single character and check whether it’s in the
list of operators. This means the pattern is simply a single period (.).
Table 17-1 shows the subpatterns that are used to create the final pattern of
“[+-]?%d*%.?%d+“ (see Chapter 6 for details).
Table 17-1: Number Subpatterns
COMPONENT PATTERN
sign (optional) [+-]?
digits (optional) %d*
decimal (optional) %.?
digits (required) %d+
Now add the following code above any of the existing functions:
local NUMBER_PATTERN = ˆ%s*([+-]?%d*%.?%d+)“
local OPERATOR_PATTERN = “ ˆ%s*(.)“
local END_PATTERN = “ ˆ%s*$“
Because the calculator will allow any amount of whitespace between num-
bers and operators, you put the target pattern inside parentheses to make it a
capture and precede it with a check for the optional whitespace: %s*.Notice
that you specify the beginning of the string immediately before the whitespace
(ˆ). If this weren’t in there, the pattern might skip over invalid syntax until it
finds a piece of valid syntax. Consider the following example:
/calculate 5 + should error here 5
10
After processing the plus sign, your code would try to match the number
pattern against the string should error here 5“. Without the start-of-string
check, the pattern will find a match at the end of the string: “5, completely
ignoring the extraneous words.
You’ll also notice that we’ve added a pattern called END_PATTERN to handle
any extra space at the end of the command.
Preparing for the Tokenization
One helpful side-effect of doing in-depth parsing is the ease with which
you can check for errors. In this calculator addon two possible errors exist:
missing/invalid number or unrecognized operator. Add the following error
strings after the patterns you just created:
local NUMBER_ERROR = “No valid number at position %d“
local OPERATOR_ERROR = “Unrecognized operator at position %d: '%s'“
Chapter 17 Creating Slash Commands 343
Errors are indicated by a flag called errorState, which is set by a custom
error function. Add the following code immediately before the calculate
function:
local errorState = false
local function reportError(message)
print(message)
errorState = true
end
Now edit the calculate function to look like the following:
local function calculate(number1, ...)
if errorState then
return
end
for i = 1, select(“#“, ...), 2 do
local operatorFunction, number2 = select(i, ...)
number1 = operatorFunction(number1, number2)
end
return number1
end
If you’re already in an error state, then you just return and do nothing. The
last change you need to make before diving into the heart of the string parsing
is to clear the error state before calling the calculate function, and replace the
string.split call with the new tokenize function you’ll be creating:
SlashCmdList[“SIMPLECALC“] = function(message)
errorState = false
print(calculate(tokenize(message)))
end
Parsing the Formula
The calculator formulas start off with a number and then are an optional
repetition of operator/number pairs. Your main tokenize function will pick
up the first number and then call a second recursive function, getpairs,to...
well ... get the subsequent pairs.
Add the tokenize function before the SlashCmdList entry with the following
code:
local function tokenize(message)
local _, finish, number = message:find(NUMBER_PATTERN)
if not number then
reportError(NUMBER_ERROR:format(1))
return
end
344 Part III Advanced Addon Techniques
The first line runs string.find to look for the first number in the formula
(remember every string has the string table as its metatable). If it doesn’t
find a number, it prints the error and returns. Finish the function with the
following code:
finish = finish + 1
if message:match(END_PATTERN, finish) == ““ then
return number
else
return number, getpairs(message, finish)
end
end
The finish variable contains the position of the last character in the found
number. In other words, if the formula is ‘‘102+5’’, finish would be 3,
corresponding to the 2 in 102. The first line of this code increments finish by
one to indicate the start of the rest of the message.
Next it looks for END_PATTERN in the message, starting at the new location.
If it matches, tokenize returns the number it found. Otherwise it returns the
number and calls getpairs to parse the rest of the message. Begin this function
just above tokenize:
local function getpairs(message, start)
local _, operatorFinish, operator = message:find(OPERATOR_PATTERN, i
start)
local operatorFunction = operators[operator]
if not operatorFunction then
reportError(OPERATOR_ERROR:format(start, operator))
return
end
As you can see, this checks for a valid operator and triggers an error if
it’s not recognized. Next, search for a number from the position just past the
operator:
operatorFinish = operatorFinish + 1
local _, numberFinish, number = message:find(NUMBER_PATTERN, i
operatorFinish)
if not number then
reportError(NUMBER_ERROR:format(operatorFinish))
return
end
And finally, finish the function just like tokenize:
numberFinish = numberFinish + 1
if message:match(END_PATTERN, numberFinish) then
return operatorFunction, number
else
Chapter 17 Creating Slash Commands 345
return operatorFunction, number, getpairs(message, numberFinish)
end
end
After reloading, you can see the earlier errors are now fixed, and bona fide
errors have sane messages:
/calculate 3 + 4
7
/calc 3+4 * 5
35
/calc 3+ 4 +
No valid number at position 7
/calc 3 + 4 & 9
Unrecognized operator at position 7: `&'
Using a Command Table
Some addons provide a single slash command with multiple, possibly nested
subcommands. For example, to show the GUI for Omen, you would use the
following command:
/omen gui show
You can easily create this kind of functionality with a relatively simple
parsing system that uses a table to represent the command hierarchy. The
parser you develop here uses a table indexed with the name of the commands.
Each entry in the table is a string, a function, or a table. If the command is a
string value, it is printed as-is. If the command is a function, the parser calls
the function with the rest of the slash command’s message. If the command is
a table, the parser treats it as another command table and processes the rest
of the message against it. If the command isn’t found, the parser looks for an
entry called ‘‘help’’ and processes it as usual.
Go ahead and create a new addon with just a Lua file and enter the following
example table:
local testCommandTable = {
[“gui“] = {
[“width“] = function(width)
print(“Setting width to“, width)
end,
[“height“] = function(height)
print(“Setting height to“, height)
end,
[“show“] = function()
print(“Showing“)
346 Part III Advanced Addon Techniques
end,
[“hide“] = function()
print(“Hiding“)
end,
[“help“] = “GUI commands: width <width>, height <height>, show, i
hide“
},
[“data“] = {
[“load“] = function(profile)
print(“Loading profile:“, profile)
end,
[“save“] = function(profile)
print(“Saving profile: “, profile)
end,
[“reset“] = function()
print(“Resetting to default“)
end,
[“help“] = “Data commands: load <profile>, save <profile>, reset“
},
[“help“] = “CommandTable commands: gui, data“
}
As you can see, this is a very concise way of defining a wide range of
functionality. That is, once you get the engine out of the way. Begin the
command processing function with the following code:
local function DispatchCommand(message, commandTable)
local command, parameters = string.split(“ “, message, 2)
local entry = commandTable[command:lower()]
local which = type(entry)
The first line of the function splits the message at the first space. Notice the
extra argument of 2, which tells string.split to return a maximum of two
strings, limiting the number of splits.
The next line retrieves the entry from the given command table, then the
function determines what type of entry it is. The rest of the function is
essentially a restatement in Lua of our earlier description:
if which == “function“ then
entry(parameters)
elseif which == “table“ then
DispatchCommand(parameters or ““, entry)
elseif which == “string“ then
print(entry)
elseif message ~= “help“ then
DispatchCommand(“help“, commandTable)
end
end
Chapter 17 Creating Slash Commands 347
Now all you need to do is tie it together with a slash command:
SLASH_COMMANDTABLE1 = “/commandtable“
SLASH_COMMANDTABLE2 = “/cmdtbl“
SlashCmdList[“COMMANDTABLE“] = function(message)
DispatchCommand(message, testCommandTable)
end
And voila! Twenty-one lines of code later and you have a powerful slash
command handler that uses a simple table for configuration. Here is some
sample output:
/cmdtbl gui show
Showing
/commandtable data
Data commands: load <profile>, save <profile>, reset
/cmdtbl GUI Width 13
Setting width to 13
Summary
In this chapter you learned the basics of slash commands and how to get
a barebones command up and running. You also examined a set of tips
and tricks you can use to make your code more flexible and cleaner. Slash
commands aren’t flashy, and in some circles they get a bad rap, but they’re
powerful, flexible, and, if implemented correctly, elegant. One very powerful
aspect of slash commands versus graphical configuration interfaces is that
slash commands can be used in macros, allowing users to change their settings
on-the-fly using buttons on their action bars.
The Code
SlashCalc
local NUMBER_PATTERN = ˆ%s*([+-]?%d*%.?%d+)“
local OPERATOR_PATTERN = ˆ%s*(.)“
local END_PATTERN = ˆ%s*$“
local NUMBER_ERROR = “No valid number at position %d“
local OPERATOR_ERROR = “Unrecognized operator at position %d: '%s'“
local errorState = false
348 Part III Advanced Addon Techniques
local function reportError(message)
print(message)
errorState = true
end
local operators = {
[“+“] = function(a, b)
return a + b
end,
[“-“] = function(a, b)
return a - b
end,
[“*“] = function(a, b)
return a * b
end,
[“/“] = function(a, b)
return a / b
end
}
local function calculate(number1, ...)
if errorState then
return
end
fori=1,select(“#“, ...), 2 do
local operatorFunc, number2 = select(i, ...)
number1 = operatorFunc(number1, number2)
end
return number1
end
local function getpairs(message, start)
local _, operatorFinish, operator = i
message:find(OPERATOR_PATTERN, start)
local operatorFunction = operators[operator]
if not operatorFunction then
reportError(OPERATOR_ERROR:format(start, operator))
return
end
operatorFinish = operatorFinish + 1
local _, numberFinish, number = message:find(NUMBER_PATTERN, i
operatorFinish)
if not number then
reportError(NUMBER_ERROR:format(operatorFinish))
return
end
Chapter 17 Creating Slash Commands 349
numberFinish = numberFinish + 1
if message:match(END_PATTERN, numberFinish) then
return operatorFunction, number
else
return operatorFunction, number, getpairs(message, i
numberFinish)
end
end
local function tokenize(message)
local _, finish, number = message:find(NUMBER_PATTERN)
if not number then
reportError(NUMBER_ERROR:format(1))
return
end
finish = finish + 1
if message:match(END_PATTERN, finish) == ““ then
return number
else
return number, getpairs(message, finish)
end
end
SLASH_SIMPLECALC1 = “/calculate“
SLASH_SIMPLECALC2 = “/calc“
SlashCmdList[“SIMPLECALC“] = function(message)
errorState = false
print(calculate(tokenize(message)))
end
CHAPTER
18
Responding to Graphic Updates
with OnUpdate
Although most code written in World of Warcraft is event-based, in certain
situations code should be run more frequently (possibly based on time).
Although there is no simple API method to accomplish this in World of
Warcraft, you can use OnUpdate scripts to fill these needs.
For example you can use OnUpdate scripts to do the following:
Delay code by a set amount of time.
Group events that fire rapidly together into a single batch to process.
Run code repeatedly, with time in between.
This chapter introduces the graphic update system that drives OnUpdate
scripts, and leads you through creating simple addons to implement each of
these scripts.
Understanding Graphic Updates
A standard measure for graphics performance in a game like World of Warcraft
is your framerate, which is measured in frames per second (FPS). The graphics
engine redraws the screen that many times to show changes to the interface
and the game world. You can view your framerate (see Figure 18-1) by
pressing Ctrl+R.
Every time the screen is redrawn, the OnUpdate script fires for any frame that
is visible (even if it has no graphical components). In addition, the arguments
to the script tell you how much time has passed since the last screen refresh.
Together, these can be used to make a very primitive (but effective) timer.
351
352 Part III Advanced Addon Techniques
Figure 18-1: Framerate being displayed in-game
Delaying Code Using OnUpdate
Say you have a function, such as one that says a random witty phrase, that
you want to run in the future. You can write a helper function that uses an
OnUpdate script to run code in the future. Run the following code in-game:
if not DelayFrame then
DelayFrame = CreateFrame(“Frame“)
DelayFrame:Hide()
end
function Delay(delay, func)
DelayFrame.func = func
DelayFrame.delay = delay
DelayFrame:Show()
end
DelayFrame:SetScript(“OnUpdate“, function(self, elapsed)
self.delay = self.delay - elapsed
if self.delay <= 0 then
self:Hide()
self.func()
end
end)
This code defines a new function called Delay() that takes a time in seconds,
and a function to be run. It sets up the DelayFrame and when the correct
amount of time has passed it calls the function. The following defines a little
bit of code that uses this function to send taunting messages during combat:
if not TauntFrame then
TauntFrame = CreateFrame(“Frame“)
end
local tauntMessages = {
“Is that the best you can do?“,
“My grandmother can hit harder than that!“,
“Now you’re making me angry!“,
“Was that supposed to hurt?“,
“Vancleef pay big for your head!“,
“You too slow! Me too strong!“,
}
Chapter 18 Responding to Graphic Updates with OnUpdate 353
TauntFrame.CHANCE = 0.5 -- Chance that a message will happen
TauntFrame.DELAY = 3.0 -- Maximum delay before a message is sent
local isDelayed = false
local function sendTauntMessage()
local msgId = math.random(#tauntMessages)
SendChatMessage(tauntMessages[msgId], “SAY“)
isDelayed = false
end
TauntFrame:RegisterEvent(“UNIT_COMBAT“)
TauntFrame:SetScript(“OnEvent“, function(self, event, unit, action, ...)
if unit == “player“ and action ~= “HEAL“ and not isDelayed then
local chance = math.random(100)
if chance <= (100 * self.CHANCE) then
local delayTime = math.random() * self.DELAY
Delay(delayTime, sendTauntMessage)
isDelayed = true
end
end
end)
First this code creates a frame so it can register events, and then it defines
a small table of taunting messages. Next, two simple configuration variables
are created and stored within the new frame. A function is created to actually
handle the choosing and sending of messages.
When the player is hit in combat and there isn’t already a delayed message
waiting to be sent, you generate a random number between 1 and 100. If
this number is less than or equal to 100 times the configured chance, the
sendTauntMessage() function is scheduled for a random time in the future.
Figure 18-2 shows this addon in action.
Figure 18-2: Taunt messages being sent during combat
The chance for the message to trigger, as well as the delay, can be con-
figured while the code is running by changing TauntFrame.CHANCE and
TauntFrame.DELAY to new values. You can experiment to find a balance
that is good for you.
354 Part III Advanced Addon Techniques
Grouping Events to Avoid Over-Processing
The following simple bit of code watches the player’s inventory and warns
him when it falls below a certain threshold. You can use the BAG_UPDATE event
to watch for changes to the player’s bags.
if not BagWatchFrame then
BagWatchFrame = CreateFrame(“Frame“)
end
BagWatchFrame.WARN_LEVEL = 0.2
BagWatchFrame.message = “You are running low on bag space!“
BagWatchFrame.fullMessage = “Your bags are full!“
local function bagWatch_OnEvent(self, event, bag, ...)
local maxSlots, freeSlots = 0, 0
for idx = 0, 4 do
maxSlots = maxSlots + GetContainerNumSlots(idx)
freeSlots = freeSlots + GetContainerNumFreeSlots(idx)
end
local percFree = freeSlots / maxSlots
local msg
if percFree == self.percFree then
-- Don’t warn the user at the same level more than once
elseif percFree == 0 then
msg = BagWatchFrame.fullMessage
elseif percFree <= self.WARN_LEVEL then
msg = BagWatchFrame.message
end
if msg then?
RaidNotice_AddMessage(RaidWarningFrame, msg, i
ChatTypeInfo[“RAID_WARNING“])
end
self.percFree = percFree
end
BagWatchFrame:RegisterEvent(“BAG_UPDATE“)
BagWatchFrame:SetScript(“OnEvent“, bagWatch_OnEvent)
This code is set to warn the player when he has less than 20% of his bag space
free. It uses the GetContainerNumSlots() and GetContainerNumFreeSlots()
functions to determine how much space each bag has, and how much is free.
When the percentage of free slots is less than BagWatchFrame.WARN_LEVEL,the
code calls RaidNotice_AddMessage() to add a message to the raid notice frame.
Figure 18-3 shows the addon warning as the player fills his last two slots.
Chapter 18 Responding to Graphic Updates with OnUpdate 355
Figure 18-3: Free slot warning displayed in the RaidWarningFrame
There is a problem with this code that can be seen when using the Equipment
Manager. The Equipment Manager is a system that allows you to save multiple
gear sets, and switch them with a single button. That’s accomplished by rapidly
equipping (or un-equipping) items as necessary. The Equipment Manager is
disabled by default, but can be enabled on the Controls menu under Interface
Options.
Depending on your latency to the server, the number of items you are
equipping or un-equipping, and the number of slots you have free in your
bags, you may find this code warning you multiple times for the same
equipment change. That is because the BAG_UPDATE event is firing more than
once in a short period of time. You can use an OnUpdate to help fix this problem,
as you see in the next section.
Grouping Multiple Events
The original code can be altered to not immediately trigger the bag scan, but
instead to schedule it for some time in the future using an OnUpdate. Edit the
code as follows, noting the highlighted differences from the previous version:
if not BagWatchFrame then
BagWatchFrame = CreateFrame(“Frame“)
end
BagWatchFrame.THROTTLE = 0.5
BagWatchFrame.WARN_LEVEL = 0.2
BagWatchFrame.message = “You are running low on bag space!“
BagWatchFrame.fullMessage = “Your bags are full!“
local function bagWatch_ScanBags(frame)
local maxSlots, freeSlots = 0, 0
for idx = 0, 4 do
maxSlots = maxSlots + GetContainerNumSlots(idx)
freeSlots = freeSlots + GetContainerNumFreeSlots(idx)
end
local percFree = freeSlots / maxSlots
local msg
if percFree == frame.percFree then
356 Part III Advanced Addon Techniques
-- Don’t warn the user at the same level more than once
elseif percFree == 0 then
msg = frame.fullMessage
elseif percFree <= frame.WARN_LEVEL then
msg = frame.message
end
if msg then
RaidNotice_AddMessage(RaidWarningFrame, msg, i
ChatTypeInfo[“RAID_WARNING“])
end
frame.percFree = percFree
end
BagWatchFrame:RegisterEvent(“BAG_UPDATE“)
local counter = 0
BagWatchFrame:SetScript(“OnUpdate“, function(self, elapsed)
counter = counter + elapsed
if counter >= self.THROTTLE then
bagWatch_ScanBags(self)
counter = 0
self:Hide()
end
end)
BagWatchFrame:SetScript(“OnEvent“, function(self, event, ...)
BagWatchFrame:Show()
end)
Rather than calling the bag scan function (which has been renamed) directly,
the OnEvent handler just shows BagWatchFrame,causingtheOnUpdate script to
fire. Once the configured amount of time has passed (in this case 0.5 seconds),
the bag scan will occur. This means that even if several BAG_UPDATE events fire
within that half-second period, the scan will only be run once.
Repeating Code with OnUpdate
You can also use OnUpdate scripts to run code repeatedly in order to perform
some periodic calculation. For example, you could alter the CombatTracker
addon you created in Chapter 14 to update the frame every second or so
during combat, giving you a running average instead of only displaying at
the end.
Add the following function to the end of CombatTracker.lua:
local throttle = 1.0
local counter = 0
function CombatTracker_OnUpdate(self, elapsed)
counter = counter + elapsed
if counter >= throttle then
Chapter 18 Responding to Graphic Updates with OnUpdate 357
CombatTracker_UpdateText()
counter = 0
end
end
Finally, you should set the OnUpdate script when the player enters combat,
and clear it when the player leaves combat. Under the PLAYER_REGEN_ENABLED
condition in CombatTracker_OnEvent(), add the following:
frame:SetScript(“OnUpdate“, nil)
Within the PLAYER_REGEN_DISABLED condition, add this line:
frame:SetScript(“OnUpdate“, CombatTracker_OnUpdate)
Now as long as you are in combat the calculation will be updated every
second.
Considering Performance with OnUpdate Scripts
Remember that the code in your OnUpdate handler is called on every screen
update. If the screen refreshes at 60 frames per second, then your script will
be called 60 times per second. As a result you should be sure to consider
performance when writing your functions. Don’t over-scrutinize your code
into some monster, but be aware that a poorly written OnUpdate script can affect
the frame rate of the client. In particular you should consider the following:
The game client runs code sequentially. As a result, all OnUpdate scripts are
run before the client continues to process events or update the graphics.
If your function does not need to run every screen refresh, you can use a
throttle to introduce a delay.
Local variables are faster than global variables, so you can squeeze out a
bit of extra performance by using them.
Summary
This chapter discussed using OnUpdate scripts to introduce delays or run code
periodically. You created a number of small addons that use OnUpdate scripts
to perform various tasks.
The next chapter introduces you to function hooking, and using a combi-
nation of an OnUpdate timer and function hooking to alter the default user
interface.
CHAPTER
19
Altering Existing Behavior
with Function Hooking
Most addons are designed as self-contained additions to the default user
interface. These addons make use of the provided API and the frames and
functionality in the default user interface. Sometimes, however, it makes sense
to alter the existing behavior of the UI. One way that can be accomplished
is known as function hooking. This chapter introduces the concept of function
hooking, including specific rules to follow and pitfalls to avoid.
What Is Function Hooking?
‘‘Hooking a function’’ is mostly just a fancy way of saying ‘‘changing the
behavior of a function.’’ Like any other Lua variable, you can overwrite a
function value with a new one of your creation. Then, any time code tries to
call the function, it will use yours instead. More specifically, though, func-
tion hooking means that the original function still runs, at least when a function
hook behaves properly.
Function hooks are used to alter the behavior of an existing function in one
of the following ways:
Altering the arguments to or the return values from the original function.
Preventing the original function from running.
Taking extra action each time the function is called.
359
360 Part III Advanced Addon Techniques
The following code, for example, adds a timestamp to any messages that are
added to the default chat frame via the ChatFrame1:AddMessage() function:
local origAddMessage = ChatFrame1.AddMessage
function ChatFrame1.AddMessage(self, text, ...)
local timestamp = date(“%X“)
text = string.format(“%s %s“, timestamp, text)
return origAddMessage(self, text, ...)
end
The first code line takes the function referenced by ChatFrame1.AddMessage
and stores it in the local variable origAddMessage. Then, a new function is
created in its place. The new function gets the current time of day and adds
it to the text argument. Finally, it calls the original function origAddMessage,
passing it the modified text.
There are a couple important points to note in the example. First, the new
function takes a variable number of arguments. The purpose of this is twofold.
Selfishly, it allows you to only pay attention to the first couple of parameters.
More importantly, though, it prevents the function from breaking expected
behavior. If the number or order of parameters ever changes in the default
UI’s AddMessage function,aslongasthetextremainsinthesameposition,
your hook will still operate as expected, and will play nicely with other code
that uses it.
TheotherpointtonoteisthattheresultsoforigAddMessage are returned as
the last step. That may seem a bit redundant because at the time of this writing
AddMessage does not return anything. However, like the use of vararg, this
practice future-proofs your function in case the default UI begins expecting a
return value. In general if you need to hook a function, someone else may also
and you should be prepared to make your replacement act like the original
function as much as possible.
Modifying Return Values
There are two basic types of function hooking. The preceding example is
what’s known as a pre-hook, indicating that the hook takes its primary action
before triggering the original function. This is directly visible in the code with
the call to (and return from) origAddMessage as the last step.
Apost-hook, on the other hand, does its business after the original function
returns. That can allow you to change return values from the function, altering
the behavior of any code that calls it. You can, of course, combine the two
techniques, although the differentiation will prove useful when you start
dealing with secure hooks.
Chapter 19 Altering Existing Behavior with Function Hooking 361
Post-hooks can be a bit trickier to get right using the preceding techniques.
First you must call the original function and store the results so you can alter
them before finally returning them. Your first inclination may be to store them
in a table, but that is difficult to do properly when the function can return nil
values.
The following sections show two different methods of getting around this
limitation when creating a function hook. These examples both work as a sim-
ple ‘‘piggy bank’’ for World of Warcraft. The GetMoney() function is hooked
and the result is altered. When you open your backpack, the amount of gold dis-
played will be different than the actual amount you have on hand. The amount
of the adjustment will be controlled by the global variable SAVED_MONEY,which
will be subtracted from the real amount of money you have.
These examples won’t prevent you from spending the money in your
invisible store; in fact, if your character has less than SAVED_MONEY money
(1 gold in the preceding example), your backpack display may show a nonsense
value because the money frames aren’t designed to show negative values.
Using a Variable Argument Function
In reality you only care about the first return from the GetMoney() function
because at the moment it only has one. You can create a pair of functions that
allows easy access that value while still being able to return any others that
may be added in the future.
SAVED_MONEY = 10000
local origGetMoney = GetMoney
local function newGetMoney(realMoney, ...)
return realMoney - SAVED_MONEY, ...
end
function GetMoney(...)
return newGetMoney(origGetMoney(...))
end
First you define the new variable SAVED_MONEY, and store a reference to the
original GetMoney() function. Next you create a helper function that will take
in the returns from the original function, altering the first one by subtracting
SAVED_MONEY from it, and returning the rest. You then create the new global
function GetMoney(), which calls the helper, passing in the results of calling
the original.
Using Utility Functions capture() and release()
The following method could potentially use a bit more memory and be less
efficient, but provides an easy way to handle storing the return values of a
362 Part III Advanced Addon Techniques
function so they can be examined and possibly altered. The trick is centered
on replacing nil values with a special marker value so the normal table
processing functions work. The capture() function is defined as follows:
function capture(...)
return { select(“#“, ...), ...}
end
capture() captures the results in a table, but adds the number of arguments
to the first slot in the table. That way, when the release function needs to return
the results, it can consult that value to ensure it returns all of the arguments.
The release function is defined as follows:
function release(tbl, index)
local size = tbl[1]
index = index or 2
if index <= size then
return tbl[index], release(tbl, index + 1)
end
end
Releasing the arguments is a bit more difficult, but still straightforward. First,
the function takes a second argument that defaults to 2, ensuring that when the
developer calls release(), he’ll get everything starting with the second slot
(remember that the number of arguments stored is in the first slot). You check
to make sure the index is in the right range, and begin returning the results.
Thesefunctionscanthenbeusedasfollows:
SAVED_MONEY = 10000
local origGetMoney = GetMoney
function GetMoney(...)
local result = capture(origGetMoney(...))
result[1] = result[1] - SAVED_MONEY
return release(result)
end
Although both of these methods may seem overly complex, they will give
you the most future-proof code. Function hooking is not something that is used
regularly in writing addons, and care must be taken when it is being used.
Hooking Widget Scripts
Hooks are often used when dealing with frame scripts. For example, your
addon may want to react to the click of some button in the default UI while
Chapter 19 Altering Existing Behavior with Function Hooking 363
still allowing the button to behave normally. Consider the Abandon Quest
button in the Quest Log that enables you to drop a quest from your log. It
currently pops up a confirmation dialog but doesn’t give any specific warning
when a quest is already complete.
ThefirststepinaframescripthookistousetheGetScript method to
retrieve the function currently used by the script handler:
local origOnClick = QuestLogFrameAbandonButton:GetScript(“OnClick“)
The GetScript() method returns either a reference to the function handler,
or nil if no handler is currently set. This is equivalent to the first line of each
of the last two examples.
WARNING Always check to see if a script is already set before replacing it, even
if the frame you’re hooking doesn’t normally specify one. Another addon may be
interested in the same button you are, and blindly replacing the script would break
that other addon. If there is no original function, you can skip that step in your
new function — but always check.
Next you need to create the replacement function:
local msg = “*** WARNING! YOU ARE ABOUT TO ABANDON A COMPLETED QUEST ***“
local function newOnClick(...)
local questIndex = GetQuestLogSelection()
local completed = select(7, GetQuestLogTitle(questIndex))
if completed then
RaidNotice_AddMessage(RaidWarningFrame, msg, i
ChatTypeInfo[“RAID_WARNING“])
end
if origOnClick then
return origOnClick(...)
end
end
The code to check and warn in this situation is relatively simple. First, you
use the GetQuestLogSelection() function to get the current selected quest
index, and then use GetQuestLogTitle() to determine whether you have
completed it yet. If so, it prints the warning and then dispatches the call to the
original handler function.
Now that you have the replacement function, you need to set it as the new
OnClick handler for the frame:
QuestLogFrameAbandonButton:SetScript(“OnClick“, newOnClick)
364 Part III Advanced Addon Techniques
Hooking a Function Securely
As Chapter 15 showed, mucking around with variables that are used by the
default UI can cause any number of problems due to taint. You may need to
hook a (seemingly benign) function for your addon, but if it’s used in any
secure code paths, the taint can have far-reaching effects.
Most times, you can accomplish your task without changing its behavior.
For this purpose, WoW provides a hooksecurefunc function that creates a
taint-free post-hook. Because the hook runs after the original function, you
cannot change the original function’s behavior. Furthermore, any returns from
your hook are discarded so you cannot change the behavior of code that calls
the hook. The signature for hooksecurefunc is as follows:
hooksecurefunc([table,] functionName, hookFunction)
Note that you can only hook functions with global names or that are
members of a table. For example, the following code prints a message every
time you press an action button or otherwise trigger UseAction.
hooksecurefunc(“UseAction“, function(slot, unit)
ChatFrame1:AddMessage(format(
“You used action %d on %s“,
slot, unit or “<no unit>“
))
end)
To hook a table method securely, simply add the table as the first argument.
For example, say you want to be notified when any code calls the Show method
on a frame.
Hooking the Show method on a frame is a bit different from responding
to the OnShow widget script. For example, if the frame is already shown and
an addon calls the Show method, this hook will respond, whereas the OnShow
script will not fire.
The following code prints a message any time you try to show someFrame:
hooksecurefunc(someFrame, “Show“, function(self)
ChatFrame1:AddMessage(“Attempting to show someFrame“)
end)
In both of these examples that you are much freer with regard to parameters
and returns. Because the returns are discarded and changing any arguments
has no effect on the rest of the code path, you can arrange your function in
whatever way makes the most sense.
Chapter 19 Altering Existing Behavior with Function Hooking 365
Hooking Scripts Securely
Reacting to a widget handler call without changing its behavior is actu-
ally simpler than the ‘‘normal’’ hook method you saw earlier. Analogous
to hooksecurefunc, every widget has a HookScript method that achieves
essentially the same result. Your new hook will be called with all the same
arguments after the original script, and any returns will be discarded. For
example, the following will safely hook the OnClick handler of your player
frame, keeping track of each time the button is clicked:
clickCounter = 0
PlayerFrame:HookScript(“OnClick“, function()
clickCounter = clickCounter + 1
print(clickCounter, “clicks and counting...“)
end)
This hook only applies to the specified button (to capture every secure
button click, use hooksecurefunc on SecureActionButton_OnClick instead).
You don’t even need to worry about checking if a script is already set;
HookScript will handle that for you!
Deciding When to Hook
Although function hooks are undoubtedly a useful tool, they do have a
few important caveats. These range from performance issues to the potential
breakage of elements in the default UI or other addons. In many cases, function
hooking is unnecessary, and there are less obtrusive alternatives.
Understanding the Hook Chain
To fully appreciate some of the problems that can arise from sloppy hooking,
think for a moment what would happen if two addons hooked the same
function. Take the GetMoney example from earlier. When any piece of code
calls GetMoney, it first activates the hook from your addon, and then your
addon calls the original function. If another addon comes along and hooks it
again, another link is added to the hook chain. The hook chain is simply a way
to visualize the interaction between the two addons and the base function. In
this example it looks like the following:
Other Addon Your Addon Built-in GetMoney
Secure hooks (via hooksecurefunc and HookScript) don’t really follow the
same chain analogy. Instead, they’re more like a key ring where each hook is a
366 Part III Advanced Addon Techniques
key. After the function does its business, the secure hook system goes through
each hook one by one, executing them independently. This does not make
them immune to the following problems, though.
You Can’t Rely on Order
Your addon has no way of knowing the order in which the hooks take place.
If the other addon is loaded before yours, the hook chain would look like this
instead:
Your Addon Other Addon Built-in GetMoney
Never rely on your addon being in a certain place in the chain. The order
of addon loading is controlled entirely by the game engine. You can buy a
little bit of leeway with dependencies and such, but that requires knowing in
advance the name of every addon that might interfere. If you find yourself
in a situation where the order matters, you should probably re-evaluate the
overall design of your addon.
There Is No ‘‘Unhook’’
Another issue the hook chain brings to the table is that it’s dangerous to
‘‘unhook’’ a function. With the earlier hook chain, if you were to remove your
hook by running GetMoney = origGetMoney,youwouldalsoberemovingthe
hook from the other addon because your origGetMoney was stored before the
other addon got a chance to hook it. More fundamentally, secure hooks are
impossible to remove; the API simply does not have any facility for it.
If you do need to unhook a function, it’s best to simply check a flag in your
hook and change the flag whenever you need to apply or remove the hook. Of
course, that leads to the next potential problem.
Hooking Hits Performance
Each hook on a given function adds a new layer of function calls. In
pseudo-code, that looks like this:
LastHook(...)
AnotherHook(...)
SecondHook(...)
FirstHook(...)
OriginalFunction(...)
return ...
return ...
return ...
return ...
At each new level, Lua has to copy the arguments so that it can call the
next function, and then copy the return values as they come back out. With
Chapter 19 Altering Existing Behavior with Function Hooking 367
secure hooks, the calls are not nested like that, but there’s still just as much
data copying going on. Most of the time, this doesn’t cause any noticeable
problems. However, if you hook a function that is called many times per
frame, you may create a perceptible drop in the performance of the client.
Finding Alternatives
We don’t want to scare you away from hooking completely; it definitely has
its time and place. However, you should consider possible alternatives first to
avoid these problems. Table 19-1 contains some common scenarios in which
your first instinct might be to hook, along with possible alternatives. Don’t
hesitate to ask for help from the UI community either. With a wider experience
base, you may end up with new ideas that help your entire addon function
more efficiently.
Table 19-1: Hooking Alternatives
POTENTIAL HOOK ALTERNATIVE
OnShow of a frame from the default
UI or another addon
Create a new frame with its own OnShow
handler as a child of the target frame. Any
time the target frame is shown or hidden,
yours will be, too. Removing your hook is
as simple as re-parenting your frame.
MerchantFrame_OnShow to
respond to opening a vendor
window
Register for the MERCHANT_SHOW event
and process the merchant data on your
own. Unregister the event to unhook. This
also prevents any conflicts if the user has
a custom merchant frame.
SetAttribute to track attribute
changes on a frame
Set or hook the OnAttributeChanged
script instead. The nature of the widget
handler fits the purpose of the hook
better than the method.
Designing an Addon: MapZoomOut
MapZoomOut is a simple addon that, whenever the player changes the zoom
of the minimap, starts a timer that returns the map to full zoom after 20 seconds.
This ensures that the player can change the zoom temporarily, but that the
map always reverts to the full size (to help with things like tracking and
tradeskills).
Specifying the behavior:
When the minimap zoom is changed via the SetZoom() method, a timer
will begin.
368 Part III Advanced Addon Techniques
When the timer reaches 20 seconds, the zoom will be changed until it is
fully zoomed out again.
Implementation details:
The Minimap:SetZoom(zoomLevel) method is used to change the zoom of
the minimap.
The minimum zoom level is 0, which is fully zoomed out.
The maximum zoom level can be obtained by calling Minimap:
GetZoomLevels().
The two minimap zoom buttons (the plus and minus) use the SetZoom()
method to change the zoom level.
When the minimap zoom buttons are used, they include logic to enable
or disable themselves (so the zoom-out button is disabled when you are
at zoom level 0).
The current zoom level can be obtained using the GetZoom() method.
To start the timer, the SetZoom()method will need to be hooked.
MapZoomOut won’t require an .xml file, so create the basic addon directory
and then add MapZoomOut.toc using the following content:
## Interface: 30200
## Title: MapZoomOut
## Notes: Zooms the map out to the full level after a given time
MapZoomOut.lua
Creating a Timer Frame
Create a new file called MapZoomOut.lua, and add the following line to the top
of the file:
local timerFrame = CreateFrame(“Frame“)
This creates a frame with no global name and assigns it to a local variable so
it can be used later in the file. It will trigger the timer with OnUpdate.
Initial Setup
Add these lines to the bottom of the MapZoomOut.lua file, creating a variable
to store the delay amount for the timer, a variable for the timer counter, and a
reference to the original Minimap:SetZoom() function:
local DELAY = 20
local counter = 0
local origSetZoom = Minimap.SetZoom
These local variables will be used later in the file to check the timer, as well
as to call the original SetZoom function.
Chapter 19 Altering Existing Behavior with Function Hooking 369
Create the Function Hook
The new function is simple; it just calls timerFrame:Show() and changes the
counter to 0to reset the timer. It then calls the original SetZoom function
to change the zoom level. Add this function definition to the bottom of
MapZoomOut.lua:
function Minimap.SetZoom(...)
-- Show the timer frame, starting the timer
timerFrame:Show()
counter = 0
-- Call the original SetZoom function
return origSetZoom(...)
end
The function parameters or returns are simply passed to the original function
using ..., and the results are returned to the calling function. This ensures
that the function will operate well with whatever calls it, because it augments
behavior rather than altering the original function.
Writing the Timer Code
The timer is a bit more complex than the earlier example simply for
aesthetic reasons. The easy way to write this addon would be to call
origSetZoom(Minimap, 0) when the timer expires, but this causes a pretty
large change in the minimap and doesn’t look all that pleasing. Instead, this
function will zoom out step by step, producing a more gradual zoom.
Add the following code to the bottom of MapZoomOut.lua:
local function OnUpdate(self, elapsed)
-- Increment the counter variable
counter = counter + elapsed
if counter >= DELAY then
-- Check current zoom level
local z = Minimap:GetZoom()
if z > 0 then
origSetZoom(Minimap, z - 1)
else
-- Enable/Disable the buttons
MinimapZoomIn:Enable()
MinimapZoomOut:Disable()
self:Hide()
end
end
end
370 Part III Advanced Addon Techniques
The beginning of the timer is the same, incrementing the counter and
checking it against the delay. Inside the conditional, you store the current
zoom level in local variable zso it can be referenced. If the minimap is
currently zoomed in (z>0), the map is zoomed out by one level, but the
counter isn’t reset. That ensures the timer’s payload will run on the next frame
update as well. This alone accomplishes the gradual zoom-out rather than the
single frame change.
Finally, once the minimap is zoomed all the way out, the MinimapZoomIn
button is enabled, and the MinimapZoomOut button is disabled. Then the timer
frame hides itself so its OnUpdate won’t be called again.
Final Setup
The last step is setting the OnUpdate script for timerFrame, and then deciding
what to do when the addon first loads. Because the user may load the game
with the minimap already zoomed in, the code will check to see if it should
start the timer or hide it to begin with (so it doesn’t run).
Add the following code to the bottom of your MapZoomOut.lua file:
timerFrame:SetScript(“OnUpdate“, OnUpdate)
if Minimap:GetZoom() == 0 then
timerFrame:Hide()
end
Testing MapZoomOut
As with any addon you create, test the functionality to ensure it works properly
with no side effects. In this case, test the following:
Using the zoom-in button, zoom in to each level, and verify that the map
is zoomed out after DELAY seconds each time.
Manually call the Minimap:SetZoom() function by running /script
Minimap:SetZoom(3). The addon should detect the change, and begin
the timer even though the buttons weren’t pushed.
Summary
Function hooking can be a useful tool in a programmer’s box, but it comes
with a hefty instruction booklet and set of warnings. In particular, follow these
principles when creating function hooks:
Use the same parameters and returns.
Call the original function and maintain the hook chain.
Don’t alter the order or meaning of arguments or returns, because other
functions may rely on them.
Chapter 19 Altering Existing Behavior with Function Hooking 371
Don’t depend on your hook being in a certain place in the chain. This also
means you should never unhook a function.
Look for alternatives first. Hooking may not always be the best solution.
In addition, special care must be taken when hooking Blizzard scripts and
functions because certain actions are restricted to the default user interface.
The Code
MapZoomOut
MapZoomOut.toc
## Interface: 30200
## Title: MapZoomOut
## Notes: Zooms the map out to the full level after a given time
MapZoomOut.lua
MapZoomOut.lua
local timerFrame = CreateFrame(“Frame“)
local DELAY = 20
local counter = 0
local origSetZoom = Minimap.SetZoom
function Minimap.SetZoom(...)
-- Show the timer frame, starting the timer
timerFrame:Show()
counter = 0
-- Call the original SetZoom function
return origSetZoom(...)
end
local function OnUpdate(self, elapsed)
-- Increment the counter variable
counter = counter + elapsed
if counter >= DELAY then
-- Check current zoom level
local z = Minimap:GetZoom()
if z > 0 then
origSetZoom(Minimap, z - 1)
else
-- Enable/Disable the buttons
372 Part III Advanced Addon Techniques
MinimapZoomIn:Enable()
MinimapZoomOut:Disable()
self:Hide()
end
end
end
timerFrame:SetScript(“OnUpdate“, OnUpdate)
if Minimap:GetZoom() == 0 then
timerFrame:Hide()
end
CHAPTER
20
Creating Custom Graphics
When creating addons for World of Warcraft, you can often build your frames
using only the default Blizzard artwork, icons, and buttons. However, if your
addon requires something more specific, it can be created using any major
graphics editor. This chapter details the major steps needed to create a custom
texture for WoW in the GNU Image Manipulation Program (GIMP), Adobe
Photoshop CS, and Corel Paint Shop Pro X.
Common Rules for Creating Graphics
Graphics (or textures) in WoW have a few specific requirements they must
meet for them to be loaded and rendered in-game as part of a custom UI:
The height and width of the texture must be a power of two, although
they do not have to be the same power of two. This means 32x256 and
512x512 are both valid, but 50x128 is not. In addition, textures are limited
to a maximum of 512 pixels in either dimension. If you have a larger
graphic, you can break it into tiles and use multiple Texture objects to
display it.
The graphic must be saved in either BLP or TGA format. BLP is a
proprietary format that Blizzard uses internally, and there are no official
tools that allow these files to be easily created or edited. TGA files can be
read and written in most major graphics editors.
373
374 Part III Advanced Addon Techniques
Textures should be saved with an 8-bit alpha channel along with the
24-bit color data. This allows for both partial and full transparency in
textures.
Graphics files must reside in an addon’s directory to be accessible to the
game client.
The GIMP
Creating a texture with transparency is relatively simple in the GIMP because
of the way it handles the alpha channel. The trick is creating the image with
a transparent background, and paying particular attention when creating the
various elements of the image.
Create a New Image
To create a new image with the GIMP:
1. Select File New in the main GIMP window.
2. In the window that appears (see Figure 20-1), enter the width and height
of your image. Keep in mind that you don’t need to fill the entire space,
but both the height and width must be a power of two.
Figure 20-1: GIMP’s New Image dialog
Chapter 20 Creating Custom Graphics 375
3. Expand the Advanced Options section of the New dialog.
4. Ensure RGB color is selected for the Colorspace.
5. Set Fill With to Transparency, so the new base image is fully transparent.
6. Click OK.
Adding Graphical Components
A new window opens showing the base transparent image (see Figure 20-2).
You can add any graphical components to this image, including layers.
Unfortunately, I’m just a simple programmer and lack any and all graphical
manipulation skills, so I can’t give you too many pointers. This example creates
a very simple custom button.
Figure 20-2: Editing window for new transparent image in the GIMP
Figure 20-3 shows a newly created custom icon, combining a simple border
graphic and a picture of my dog Daisy. This image is 64x64 and has transparent
edges (specifically for the rounded corners).
Figure 20-3: New custom icon created in the GIMP
376 Part III Advanced Addon Techniques
Saving Textures
As long as the graphic was created with a transparent background, you should
be able to save it without any issues. Save the new image using the following
steps:
1. Merge all the layers before attempting to save because TGA does not sup-
port layers. This step isn’t necessarily required but makes the subsequent
steps easier.
2. Select File Save.
3. In the Save dialog, name your file with a .TGA extension and click the
Save button.
4. An options dialog pops up (shown in Figure 20-4). Check both checkboxes
and click OK. This compresses the image in a lossless way (so it loses no
quality) but creates a smaller file size.
Figure 20-4: Save as TGA dialog in the GIMP
Personally, I find that creating images in the GIMP the easiest, because the
only trick is ensuring the image is the right size with a transparent background.
Adobe Photoshop
Creating a texture in Photoshop is similar to creating one in the GIMP, but the
interface is quite a bit different. The same basic steps apply, the image creation
and saving being the most important.
Create a New Image
To create a new image with Photoshop:
1. Open Photoshop and select File New.
2. The New dialog opens (see Figure 20-5).
3. Change the height and width to your desired dimensions.
4. Ensure the Background Contents dropdown has Transparent selected.
5. Click OK to create the new image.
Chapter 20 Creating Custom Graphics 377
Figure 20-5: Adobe Photoshop file creation dialog
Adding Graphical Components
Create the graphic as required (you’re the one familiar with Photoshop here),
but take care to follow these rules:
Make sure there isn’t a Background layer in your document when you
are ready to save.
If you need to merge visible layers, use Merge All, but don’t flatten
the image. Flattening the image gives it a background, which loses the
transparency information.
Transparency in Adobe Photoshop is different than in GIMP. In particular,
you won’t see an alpha channel created by default in the Channels window.
The transparent background means nothing when the image is flattened and
saved. To achieve transparency, you must create the alpha channel.
Creating an Alpha Channel
When your image is complete and ready to save, run the following steps to
create an alpha channel:
1. Merge the visible layers so you have a single layer containing the
nontransparent portions of your image.
2. Select the layer in the layers palette.
3. Open the Select menu and select Load Selection.
4. You will be prompted with a dialog box (see Figure 20-6), but the default
options should be correct. Click OK. This selects each pixel in the current
layer that isn’t transparent.
378 Part III Advanced Addon Techniques
Figure 20-6: Load Selection dialog
5. In the Channels window, there is a small icon that will ‘‘Save Selection
As Channel’’ (see Figure 20-7). Click it, creating an alpha channel based
on the selection.
Figure 20-7: Save Selection As Channel button in the Channels window
The new 8-bit alpha channel gives you different levels of opacity for an image
with more forgiving transparency. Now that the transparency information is
stored in a channel, you can flatten the image if you’d like (although there
is no compelling reason to do so).
Saving an Image
Once the alpha channel is created, saving the image is a matter of selecting
File Save As. The Save As dialog provides several options (shown in
Figure 20-8).
Chapter 20 Creating Custom Graphics 379
Figure 20-8: Options in Photoshop’s Save As dialog
You can choose any name you’d like for the image, but ensure the file
format is set to Targa (*.tga) and that the filename ends in the .tga exten-
sion. If your image has layers, the As A Copy option will be automatically
selected, and the Layers option will be deselected with an error warning
next to it. This simply means that TGA doesn’t support layers, so the image
will be flattened before saving. Ensure that Alpha Channels is selected.
Click Save.
A final TGA options dialog (see Figure 20-9) opens to allow you to select the
color resolution and add compression to the image. Select 32 bits/pixel, and
check the box for Compress (RLE).
Figure 20-9: Targa Options dialog
Once the image is saved, it can be copied into your WoW installation and
tested.
Paint Shop Pro
Paint Shop Pro is similar to Adobe Photoshop in most respects, particularly in
the way it handles transparency. As a result, you’ll need to take similar steps
to ensure the transparent images you create are saved correctly.
380 Part III Advanced Addon Techniques
Creating a New Image
To create a new image with Paint Shop Pro:
1. Select File New.
2. The New Image options dialog (see Figure 20-10) opens. Specify the
dimensions of your image.
Figure 20-10: Corel Paint Shop Pro New Image dialog
3. Select a Raster Background with a color depth of RGB - 8 bits/channel.
4. Check the Transparent box to give your image a transparent background.
5. Click OK.
Adding Graphical Components
Create your image as you usually do in this application, ensuring that you
don’t use the Flatten Image option. You will need the transparent background
to make certain the alpha channel is created correctly.
Chapter 20 Creating Custom Graphics 381
Creating an Alpha Channel
Once your image is created, use the following steps to create an alpha channel
for transparency:
1. Select Layers New Mask Layer From Image (see Figure 20-11). This
will create a new mask layer consisting only of the pixels in your image.
Figure 20-11: New Mask Layer menu option
2. In the Add Mask From Image dialog (see Figure 20-12), select Source
Opacity in the Create Mask From section to ensure the new alpha channel
is created using the transparency you defined when creating the image.
Figure 20-12: Add Mask From Image dialog box
3. Click OK. This adds a new layer mask to your image.
4. Select Layers Load Save Mask Save Mask to Alpha Channel.
5. A dialog box displays, allowing you to preview the image transparency
and giving you an opportunity to name the new channel. Click OK.
382 Part III Advanced Addon Techniques
Your image now has a proper alpha channel that can be used to save the
image with transparency.
Saving an Image
Follow these steps to save an image in Paint Shop Pro:
1. Select File Save As.
2. In the dialog that appears, choose TGA Truevision targa (*.tga) as the
image format, and name your image.
3. Click the Options button.
4. In the Save Options dialog box (see Figure 20-13), select a 24-bit image
and compression for your image.
5. Click OK to exit the options dialog.
Figure 20-13: Targa options in Paint Shop Pro
6. Click Save.
7. If you still have layers in your image, you may get a warning dialog (see
Figure 20-14) telling you that the image will be merged and then saved.
Click Yes.
Figure 20-14: File format limitations dialog in Paint Shop Pro
Chapter 20 Creating Custom Graphics 383
Testing Your Texture
To test the new texture, you need to fully exit World of Warcraft and add
a small custom addon to house the image. (You could instead add it to an
existing addon, but that exercise is left to the reader, when appropriate.)
1. Create a folder IconTest underneath your AddOns directory.
2. Add a file IconTest.toc with the following contents:
## Interface: 30200
## Title: IconTest
## Notes: Simple icon test addon
IconTest.xml
3. Add a file IconTest.xml with the following contents. Change DaisyIcon
to the name of your icon filename.
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Button name=“IconTest“ parent=“UIParent“>
<Size x=“64“ y=“64“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Layers>
<Layer level=“BACKGROUND“>
<Texture name=“$parentIcon“ i
file=“Interface\AddOns\IconTest\DaisyIcon“ setAllPoints=“true“/>
</Layer>
</Layers>
</Button>
</Ui>
4. WoW doesn’t require you to specify extensions when loading textures; it
will try to load both a .BLP and a .TGA automatically.
5. Copy your icon file to the IconTest directory.
6. Load up World of Warcraft and hope you don’t have any errors in your
XML.
If you have created the texture correctly, it should appear in the center of
your screen (see Figure 20-15).
If you’ve made any errors, you might experience one of two symptoms: no
button appears, or you see only a solid green box.
384 Part III Advanced Addon Techniques
Figure 20-15: Custom texture being viewed in-game
No Button Appears
If you see no button at all, double-check your XML definition, and ensure you
have no errors in your FrameXML.log file. You can also use a web browser to
check that your XML document is well-formed. Ensure that your test addon
appears in the AddOn listing. Did you make sure to exit WoW before you
added the new files?
A Green Box Appears
When there is an issue loading a given texture in World of Warcraft, the texture
will be colored solid green (see Figure 20-16). Typically, this is a result of a
typo on the filename being used for the texture.
Figure 20-16: Solid green texture, indicating an error
Depending on how the texture was created (from an XML definition or
through a Lua function call), a number of issues could result in a green texture
being displayed.
XML Texture Definition
A texture created in XML may have one of the following issues:
The file doesn’t exist.
The graphic was saved incorrectly.
The filename was not specified correctly.
Filenames in XML should only have single backslashes between
directories.
Chapter 20 Creating Custom Graphics 385
Filename path separators must be backslashes, even on a Mac OS X
or UNIX system, because of the way the client loads and parses the
filenames.
Lua Texture Definition
When troubleshooting texture errors in Lua, the following issues may exist:
The file doesn’t exist.
The graphic was saved incorrectly.
The filename was not specified correctly.
Backslashes in filenames must be escaped (using a double backslash).
Alternatively, you can use long string notation to specify the filename:
[[Interface\AddOns\YourAddOnName\Path\To\Texture]]
Filename path separators must be backslashes, even on a Mac OS X
or UNIX system, because of the way the client loads and parses the
filenames.
Summary
Every graphical editor has differences and settings that are necessary to create
an image with partial transparency for use in World of Warcraft. The GIMP
enables you to create your image and simply save it as a TGA file, whereas
both Photoshop and Paint Shop Pro require you to create an alpha channel
based on a mask or selection.
CHAPTER
21
Responding to the Combat Log
and Threat Information
Following the Burning Crusade expansion for World of Warcraft, a new system
was introduced to allow addons to get detailed information about the combat
events happening around the player. The system allows for very powerful
addons that can record and display combat log information. This chapter
introduces you to the complex combat log system through the creation of an
addon called CombatStatus.
Understanding the Combat Log
The combat log is one of the most complex systems in World of Warcraft,
which is understandable considering how much of the game is actually based
around combat. An addon can use two events to get combat log information,
COMBAT_LOG_EVENT and COMBAT_LOG_EVENT_UNFILTERED. The first event is used
by the actual Blizzard_CombatLog addon to display filtered events, and the
second will fire for any combat event regardless of whether or not it matches
the currently set filters. Most addons will use the unfiltered event to ensure
that players get an opportunity to see each event.
Event Arguments
Each combat event is guaranteed to have at least eight arguments that describe
the different actors involved in the combat event. Not all events will have two
actors (a source and a destination) because that information isn’t necessarily
387
388 Part III Advanced Addon Techniques
available. The standard arguments to the event appear in the following
order:
timestampThis is a server-based timestamp of when the event occurred,
with millisecond precision. If you are logging events or comparing events
between clients, this can help with matching different events up with
each other.
combatEventMore than forty different combat events might be sent as
a combat log event and this argument helps to distinguish between these
different sub-events. Example sub-events are UNIT_DIED,SPELL_STOLEN,
and SWING_DAMAGE. There’s more information about the different combat
events in the next section.
sourceGUIDEach unit (or other entity) involved in a combat log event
is distinguished by a GUID (Globally Unique IDentifier). These values
exist for all entitiesincluding those which cannot be referenced by
unitIDand always specifically identify the entity to which they refer
even for cases where multiple units share the same name. This allows
addons to keep track of individual actors in combat regardless of such
factors. Further explanation of GUIDs is provided later in this chapter.
sourceNameBecause the combat log is most interested in displaying the
name of the actor, it makes sense to include that in the event arguments.
This is the name of the source actor for the given combat event.
sourceFlagsThis field contains information about the actor, such as
whether it is a non-player character, a pet, or some other type of object.
In addition the flags contain information about the relationship between
the player and the actor, such as whether or not it was the player’s target
at the time the event occurred.
destGUIDThe same information as sourceGUID for the destination actor.
destNameThe same information as sourceName for the destination actor.
destFlagsThe same information as sourceFlags for the destination
actor.
There are normally additional event arguments, but they change depending
on the type of combatEvent.
Combat Sub-Events
To determine the particular arguments and information being passed in a
combat log event, you must examine the combatEvent argument. Currently
forty-eight different types of sub-events might occur, but even sub-events can
be split further into a prefix and a suffix.
Chapter 21 Responding to the Combat Log and Threat Information 389
Combat Event Prefix
The event prefix indicates the type of the event, such as whether it involves
physical damage like an auto-attack, a ranged attack, spell, or damage to
a building or structure in-game. The additional arguments will be after the
initial eight arguments that come with the COMBAT_LOG_EVENT_UNFILTERED.
SWINGThis prefix is encountered for any auto-attack damage. No addi-
tional arguments are sent for this type of event prefix.
RANGEAny ranged attacks, such as auto shot, shoot bow/gun/
crossbow/wand, and throwing, will use this prefix, which sends the spell
information as additional arguments. The spell information is passed in
additional arguments: spellId,spellName,andspellSchool.
SPELLThis prefix is used for all spellcast events, as well as other types of
non-periodic spell actions. The spell information is passed in additional
arguments: spellId,spellName,andspellSchool.
ENVIRONMENTALThis prefix is used for damage caused by the environ-
ment, such as when a player touches a bonfire, is immersed in lava, falls
from great height, or begins to drown. The type of environmental damage
is passed as an additional argument: environmentType.
Bit Fields and Spell Schools
Throughout the combat log, bit fields are used for arguments where more than
one setting might be set in a single argument. The term bit field comes from the
binary representation of numbers, where a number is made up of a number
of bits. Table 21-1 shows the basic spell schools with their numeric values and
binary representation.
Table 21-1: Spell Schools and Numeric Representations
SPELL SCHOOL NUMERIC VALUE BINARY REPRESENTATION
Physical 1 00000001
Holy 2 00000010
Fire 4 00000100
Nature 8 00001000
Frost 16 00010000
Shadow 32 00100000
Arcane 64 01000000
Frostfire 20 00010100
390 Part III Advanced Addon Techniques
You can see that the binary values are non-conflicting and as a result they
can be combined. The spell school for Frostfire Bolt (20) combines the value
for Frost (16) and Fire (4). More importantly, we can get the component values
back out of the combined number using bitwise operations. Try the following
within WoW:
> print(bit.band(20, 16))
16
> print(bit.band(20, 4))
4
> print(bit.band(20, 8))
0
As a matter of fact, there’s only one way to build the number 20 by adding
the basic spell schools together. Even if you were to add the physical, holy, fire,
and nature schools together, you would only get to 15. You could try adding
the physical holy and frost schools together but that only gets you to 19. This
is a special feature of bit masks that are built in this way.
To compare bit fields, you can utilize the three major bitwise operations:
and—The bitwise and of two numbers is a resulting number where each
bit is set to 1 only if the same bit is set to 1 for the two input numbers.
This function is available as the bit.band() function.
or—The bitwise or of two numbers is a resulting number where each bit
is set to 1 if either of the input bits is set to 1. This function is available as
the bit.bor() function.
xor—The bitwise xor of two numbers is a resulting number where each
bit is set to 1 if exactly one of the two input bits is set to 1. This function
is available as the bit.bxor() function.
In practice, you will very rarely use anything other than bitwise and because
it allows you to see if a given bit flag is set for a given number. In the preceding
examples, you take the number 20 (which is 00010100 in binary representation)
and compare it to 16 (00010000), 4 (00000100), and 8 (0001000).
All you have to do is check the resulting number to see if it’s greater than 0
(that is, if there are any bits set). You experiment more with bit masks later in
this chapter.
Combat Event Suffix
The rest of the combat event following the prefix indicates the remaining argu-
ments to the combat event. The arguments will start following any additional
arguments from the prefix portion of the combat event. The particular order
Chapter 21 Responding to the Combat Log and Threat Information 391
will make more sense when you look at complete events put together. The
following is a list of valid suffix types:
DAMAGE and BUILDING_DAMAGEUsed to indicate damage to the destina-
tion actor. If the damage was done to a building rather than a normal
unit, the BUILDING_DAMAGE event will fire instead of DAMAGE. The following
additional arguments are included:
amountThe amount of damage inflicted.
overkillA number, zero or more, indicating how much overkill
damage was inflicted (that is, how much extra damage was done
beyond the amount required to kill/destroy the target).
schoolThe school of the inflicted damage, that is, whether the
damage was physical, caused by fire, and so on.
resistedA number, zero or more, indicating how much damage
was resisted due to magical resistance attributes.
blockedA number, zero or more, indicating how much damage was
blocked due to a physical shield.
absorbedA number indicating how much damage was absorbed by
a spell or ability, or nil.
critical1if the damage inflicted was a critical hit, otherwise nil.
glancing1if the damage inflicted was a glancing blow, other-
wise nil.
crushing1if the damage inflicted was a crushing blow, other-
wise nil.
MISSED and PERIODIC_MISSEDUsed to indicate that an attack missed in
some way. The following arguments are included:
missTypeOne of the following strings, indicating the type of miss
that occurred: ABSORB,BLOCK,DEFLECT,DODGE,EVADE,IMMUNE,MISS,
PARRY,REFLECT,andRESIST.
amountMissedThe amount of damage that missed.
CAST_STARTThis combat event is only fired for the SPELL prefix, and
indicates the start of a spell cast. This only fires for spells with a cast time.
No additional arguments are included.
CAST_SUCCESSThis combat event is fired for any type of spell cast
including channeled and instant cast spells. It indicates that the spell was
cast successfully. No additional arguments are included.
392 Part III Advanced Addon Techniques
CAST_FAILEDThis combat event is fired whenever a spell cast has failed
for some reason. The following additional argument is included:
failedTypeA message indicating why the spell cast failed.
HEAL,PERIODIC_HEAL,andBUILDING_HEAL One of these combat events
fires when a healing effect occurs. Depending on whether the spell is a
periodic effect, a heal on a building, or a one-shot heal on a unit, one of
these three events will fire. The following arguments are included:
amountThe amount of healing that occurred.
overhealingA number, zero or greater, indicating the amount of
healing that occurred beyond that required to bring the target to full
health.
absorbedA number indicating the amount of healing that was
absorbed.
critical1if the heal was a critical heal, otherwise nil.
ENERGIZE and PERIODIC_ENERGIZEEnergize events occur when an actor
gains health, mana, or some other type of power through some abil-
ity or item. Depending on whether the spell is a periodic effect or
a one-shot effect, one of these two events will fire. For example, the
ENERGIZE event fires when the Death Knight ‘‘Butchery’’ effect is trig-
gered, giving the player 20 extra runic power. The following arguments
are included:
amountThe amount of power gained.
powerTypeThe type of power that was gained. It can be one of the
following values:
-2—Health
0—Mana
1—Rage
2—Focus (pets)
3—Energy
4Pet happiness
5—Runes
6—Runic power
LEECH and PERIODIC_LEECHWhen one actor ‘‘steals’’ a resource from
his target, such as when using the Viper Sting or Drain Mana spells, one
of these events will occur. Depending on whether the spell is a periodic
Chapter 21 Responding to the Combat Log and Threat Information 393
effect or a one-shot effect, one of these two events will fire. The following
arguments are included:
amountThe amount of power gained.
powerTypeThe type of power that was gained. See the listing for the
ENERGIZE suffix.
extraAmountThe extra amount of power that was gained as a bonus of
the spell. For example, Viper Sting awards 300% of the power leeched.
DRAIN and PERIODIC_DRAINWhen one actor drains a resource from his
target, one of these events will occur. Depending on whether the spell is
a periodic effect or a one-shot effect, one of these two events will fire. The
following arguments are included:
amountThe amount of power gained.
powerTypeThe type of power that was gained. See the listing for the
ENERGIZE suffix.
extraAmountThe extra amount of power that was gained as a bonus
of the spell. For example, Viper Sting awards 300% of the power
leeched.
Spell-Only Suffixes
The following combat suffixes only fire for the SPELL prefix:
SUMMONFires when an actor summons an NPC such as a totem or
non-combat pet. No additional arguments are included.
RESURRECTFires when a player is resurrected. No additional arguments
are included.
CREATEFires when a new object is created (as opposed to summoned
NPCs), such as a hunter’s pet or mage portal. No additional arguments
are included.
INSTAKILLFires when a spell instantly kills an actor. No additional
arguments are included.
INTERRUPTFires when a spell is interrupted. The first set of spell
arguments (from the prefix) will be the ability that was responsible for
the interruption. The following arguments are included:
extraSpellIDThe numeric identifier for the spell that was
interrupted.
extraSpellNameThe name of the spell that was interrupted.
extraSchoolThe school of the spell that was interrupted.
394 Part III Advanced Addon Techniques
EXTRA_ATTACKSFires when an actor does additional damage through
extra attacks, such as those granted by Windfury Weapon or the Thrash
Blade proc. The following argument is included:
amountThe number of extra attacks granted by the ability. The actual
damage is listed as additional entries in the combat log.
DURABILITY_DAMAGEThis event fires when a spell or ability causes dam-
age to an actor’s items. For example, Nefarion’s hunter call in Blackwing
Lair or Ragnaros’ Melt Weapon ability, which reduce the durability of the
player’s items.
DURABILITY_DAMAGE_ALLThis event fires when a spell or ability causes
damage to all of an actor’s items.
AURA_APPLIEDFires when an aura is applied to an actor. The following
argument is included:
auraTypeA string indicating the type of the aura. Observed values
are BUFF and DEBUFF.
AURA_APPLIED_DOSEFires when a stackable aura is applied to an actor,
such as Lifebloom or Penance. The following arguments are included:
auraTypeA string indicating the type of the aura. Observed values
are BUFF and DEBUFF.
amountThe number of doses applied.
AURA_REFRESHFires when an aura is refreshed with a new application.
The following argument is included:
auraTypeA string indicating the type of the aura. Observed values
are BUFF and DEBUFF.
AURA_REMOVEDFires when an aura is removed from an actor. The fol-
lowing argument is included:
auraTypeA string indicating the type of the aura. Observed values
are BUFF and DEBUFF.
AURA_REMOVED_DOSEFires when a dose is removed from a stackable aura,
such as Lifebloom or Penance. The following arguments are included:
auraTypeA string indicating the type of the aura. Observed values
are BUFF and DEBUFF.
amountThe number of doses removed.
AURA_BROKENFires when an aura has been broken by damage. The
following argument is included:
auraTypeA string indicating the type of the aura. Observed values
are BUFF and DEBUFF.
Chapter 21 Responding to the Combat Log and Threat Information 395
AURA_BROKEN_SPELLFires when an aura has been broken by a spell. The
following arguments are included:
extraSpellIDThe numeric identifier for the spell that was broken.
extraSpellNameThe name of the spell that was broken.
extraSchoolThe school of the spell that was broken.
auraTypeA string indicating the type of the aura. Observed values
are BUFF and DEBUFF.
DISPELFires when an aura is dispelled. The following arguments are
included:
extraSpellIDThe numeric identifier for the spell that was dispelled.
extraSpellNameThe name of the spell that was dispelled.
extraSchoolThe school of the spell that was dispelled.
auraTypeA string indicating the type of the aura. Observed values
are BUFF and DEBUFF.
DISPEL_FAILEDFires when an aura fails to be dispelled. The following
arguments are included:
extraSpellIDThe numeric identifier for the spell that was dispelled.
extraSpellNameThe name of the spell that was dispelled.
extraSchoolThe school of the spell that was dispelled.
auraTypeA string indicating the type of the aura. Observed values
are BUFF and DEBUFF.
STOLENFires when an aura is stolen. The following arguments are
included:
extraSpellIDThe numeric identifier for the spell that was stolen.
extraSpellNameThe name of the spell that was stolen.
extraSchoolThe school of the spell that was stolen.
auraTypeA string indicating the type of the aura. Observed values
are BUFF and DEBUFF.
Special Combat Events
The following combat events do not follow the prefix/suffix conventions and
therefore must be considered individually:
DAMAGE_SHIELDFires when a shield causes damage to an actor. To
process this event you can use the same arguments for the SPELL prefix,
with the additional arguments from the DAMAGE suffix.
396 Part III Advanced Addon Techniques
DAMAGE_SPLITThis occurs when damage is split among multiple targets.
To process this event you can use the same arguments for the SPELL prefix,
with the additional arguments from the DAMAGE suffix.
DAMAGE_SHIELD_MISSEDFires when a shield causes damage to an actor,
but that damage misses in some way. To process this event you can use
thesameargumentsfortheSPELL prefix, with the additional arguments
from the MISSED suffix.
ENCHANT_APPLIEDFires when an enchantment is applied to an item. The
following arguments are passed:
spellNameThe name of the enchantment.
itemIDThe numeric identifier of the item.
itemNameThe name of the item that was enchanted.
ENCHANT_REMOVEDFires when an enchantment is removed from an item.
The following arguments are passed:
spellNameThe name of the enchantment.
itemIDThe numeric identifier of the item.
itemNameThe name of the item that was enchanted.
PARTY_KILLFires when a member of your party kills a unit.
UNIT_DIEDFires when a unit dies.
UNIT_DESTROYEDFires when a unit is destroyed.
Unit GUIDs
All units in World of Warcraft have a globally unique identifier. From the
details posted by Blizzard on the WoW Forums:
An NPC has a single GUID from spawn until death or despawn. When it
respawns, it gets a new GUID.
Pets and totems get a new GUID every time they are summoned.
NPC and pet GUIDs can be recycled after server or instance restart.
Player GUIDs are unique and persist as long as the player is on a given
server.
The combat log automatically sends the GUID for the source and destination
unit for each event. In addition, you can query the GUID for a specific unit
using the UnitGUID() function. Recently a new function was added, allowing
you to query class, race, and sex information about another player unit using
Chapter 21 Responding to the Combat Log and Threat Information 397
his GUID. The GetPlayerInfoByGUID() function takes in a GUID argument,
and returns the following:
localizedClassThe name of the unit’s class in the client’s current
locale.
classFilenameA non-localized token identifying the unit’s class (which
can be used for looking up other class identifiers, such as color values in
the RAID_CLASS_COLORS table).
localizedRaceThe name of the unit’s race in the client’s current locale.
raceFilenameA non-localized token identifying the unit’s race.
sexA number identifying the unit’s gender: 1 for neuter or unknown,
2formale,or3forfemale.
Format of GUIDs
Due to the large amount of items that require GUIDs, they are quite large
numbers. In fact, the numbers are bigger than the numbers that Lua can hold in
their number values. As a result, the GUIDs are stored and returned as strings.
For example “0x0100000002AB26D5“ is the GUID of one of my characters.
Internally, parts of the GUID are bit fields as well. For example, you can
determine whether or not the entity behind a GUID is a player, NPC, or pet.
To do this, you need to convert your GUID string to a number and take the
mask of the upper portion:
function GUIDToType(guid)
local typeMask = 0x00F
local upper = tonumber(guid:sub(1, 5))
local type = bit.band(upper, typeMask)
if type == 0 then
print(“GUID “ .. guid .. “ is a player“)
elseif type == 3 then
print(“GUID “ .. guid .. “ is an NPC“)
elseif type == 4 then
print(“GUID “ .. guid .. “ is an NPC“)
end
end
GUIDToType(UnitGUID(“player“))
Other information is embedded in the GUID for most units but isn’t used
for our purposes. GUIDs do provide you with a way to get information about
entities in your combat log which cannot be identified by a unitID, but note
that the format of such information may be subject to change.
398 Part III Advanced Addon Techniques
Unit Flags
The final argument that is sent for the source and destination is a set of flags.
These flags indicate the following information about each entity:
The type of the entity as one of the following: object, guardian, pet, NPC,
or player.
Whether the entity is controlled by a player or is an NPC.
The entity’s reaction to the player (that is, friendly, hostile, or neutral).
The relationship between the player and the entity’s controller. This rela-
tionship can be the player, the player’s party, the player’s raid, or an
outsider.
If the entity is a raid target, main tank, main assist, or the player’s focus
or target unit at the time the message is received.
You use bitwise operations to get this information.
COMBATLOG_OBJECT_TYPE_MASK
To obtain the type of an object, you can use the global variable COMBATLOG_
OBJECT_TYPE_MASK. You then compare the resulting value with one of the
following global variables:
COMBATLOG_OBJECT_TYPE_MASK
COMBATLOG_OBJECT_TYPE_GUARDIAN
COMBATLOG_OBJECT_TYPE_PET
COMBATLOG_OBJECT_TYPE_NPC
COMBATLOG_OBJECT_TYPE_PLAYER
For example, to check if the entity with given unit flags is a pet, you can use
the following code:
local typeFlags = bit.band(unitFlags, COMBATLOG_OBJECT_TYPE_MASK)
local isPet = typeFlags == COMBATLOG_OBJECT_TYPE_PET
COMBATLOG_OBJECT_CONTROL_MASK
You can utilize this mask to determine if a player or an NPC currently controls
an entity. These flags do properly update when entities are mind controlled,
allowing you to distinguish between an ally of yours attacking the enemy
and an ally of yours attacking you under duress. The valid results for these
flags are:
COMBATLOG_OBJECT_CONTROL_NPC
COMBATLOG_OBJECT_CONTROL_PLAYER
Chapter 21 Responding to the Combat Log and Threat Information 399
COMBATLOG_OBJECT_REACTION_MASK
The reaction of an entity is a bit misleadingyou might think that if an enemy
is attacking you or one of your allies they would show up as hostile. Instead,
the reaction indicates the predisposition of an entity toward the player. As a
result, one of the yellow-colored mobs in the game that won’t automatically
attack you will show up as having a neutral reaction to you even if it’s
fighting you!
The valid results for these flags are:
COMBATLOG_OBJECT_REACTION_HOSTILE
COMBATLOG_OBJECT_REACTION_NEUTRAL
COMBATLOG_OBJECT_REACTION_FRIENDLY
COMBATLOG_OBJECT_AFFILIATION_MASK
An object’s affiliation indicates its relationship to the player. The possible
results start with the closest to the player (that is, something that is owned by
the player) and move out to outsiders (entities that are not part of the player’s
raid or party). Possible results are:
COMBATLOG_OBJECT_AFFILIATION_OUTSIDER
COMBATLOG_OBJECT_AFFILIATION_RAID
COMBATLOG_OBJECT_AFFILIATION_PARTY
COMBATLOG_OBJECT_AFFILIATION_MINE
The numeric values of the global variables starts with 1 for MINE and
increases toward OUTSIDER with 8. Although we recommend against relying
on the numeric values of these variables rather than using the global constants,
the ordering of the values isn’t likely to change in the future without notice.
You could therefore check to see that something is either owned by you or
someone in your party by checking that the result is less than or equal to
COMBATLOG_OBJECT_AFFILIATION_PARTY.
COMBATLOG_OBJECT_SPECIAL_MASK
The special flags are used to indicate if the entity has some special way to be
distinguished, from the player’s perspective. An entity might have no special
flags set, giving the result:
COMBATLOG_OBJECT_NONE
The flags might indicate that the entity has one of the eight raid icons on it:
COMBATLOG_OBJECT_RAIDTARGET8
COMBATLOG_OBJECT_RAIDTARGET7
400 Part III Advanced Addon Techniques
COMBATLOG_OBJECT_RAIDTARGET6
COMBATLOG_OBJECT_RAIDTARGET5
COMBATLOG_OBJECT_RAIDTARGET4
COMBATLOG_OBJECT_RAIDTARGET3
COMBATLOG_OBJECT_RAIDTARGET2
COMBATLOG_OBJECT_RAIDTARGET1
The entity might have been set as a Main Tank or Main Assist:
COMBATLOG_OBJECT_MAINTANK
COMBATLOG_OBJECT_MAINASSIST
In addition the flags could indicate that the entity was the player’s target or
focus at the time the event arrived (although it may have since changed):
COMBATLOG_OBJECT_FOCUS
COMBATLOG_OBJECT_TARGET
Using CombatLog_Object_IsA
There is a utility function that can make working with combat log flags a bit
easier. It takes in a set of unit flags and a ‘‘filter’’ mask. If the unit matches the
given mask, it returns 1; otherwise it returns nil. These predefined filters are
as follows:
COMBATLOG_FILTER_EVERYTHINGAny entity.
COMBATLOG_FILTER_FRIENDLY_UNITSEntity is a friendly unit.
COMBATLOG_FILTER_HOSTILE_PLAYERSEntity is a hostile player unit.
COMBATLOG_FILTER_HOSTILE_UNITSEntity is a hostile non-player unit.
COMBATLOG_FILTER_MEEntity is the player.
COMBATLOG_FILTER_MINEEntity is a non-unit object belonging to the
player; for example, a totem.
COMBATLOG_FILTER_MY_PETEntity is the player’s pet.
COMBATLOG_FILTER_NEUTRAL_UNITSEntity is a neutral unit.
COMBATLOG_FILTER_UNKNOWN_UNITSEntity is a unit currently unknown
to the WoW client.
Chapter 21 Responding to the Combat Log and Threat Information 401
Writing CombatStatus
As an example of how the combat log can be used to get detailed information
about combat in World of Warcraft, you will create an addon called Com-
batStatus. The initial version will show the damage per second and heals per
second for your party, including pets.
The addon is structured with the following observations in mind:
You can take advantage of unit flags to make capturing all of your
party’s events easier. In particular, you can check for COMBATLOG_OBJECT_
AFFILIATION_PARTY to get the relevant events.
Because combat data arrives with GUID information rather than unitIDs,
you’ll need to make sure you store and index all data using GUIDs. This
will ensure that you don’t lose any information if the order of unitIDs
change.
A player might have more than one pet (for example, druids and their
treant pets, or shaman elemental totems). Rather than trying to consider
them individual pets, you can just collapse them into a single ‘‘pet’’ unit
for each of your party members. You can use the SPELL_SUMMON combat log
event to detect new units coming into play so we can track their GUIDs.
Creating the Basic Addon Structure
In your Addons folder, create a new directory called CombatStatus. Inside,
create a new file called CombatStatus.toc with the following contents:
## Interface: 30300
## Notes: Provides a DPS meter for your party
CombatStatus.lua
CombatStatus.xml
Although you aren’t using any XML templates in this addon currently, it’s
better to create the file now in case you choose to add some at a later time. Create
anewCombatStatus.xml file and add the basic <Ui> element declaration:
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
</Ui>
402 Part III Advanced Addon Techniques
To add the frame declaration and a system for initialization that you’ll
expand on in later sections, create a new file CombatStatus.lua with the
following contents:
local CombatStatus = CreateFrame(“Frame“, “CombatStatus“, UIParent)
function CombatStatus:OnEvent(event, ...)
if event == “PLAYER_LOGIN“ then
self:Initialize()
end
end
-- Begin initialization section
-- Set the event handler so it can drive everything else
CombatStatus:SetScript(“OnEvent“, CombatStatus.OnEvent)
if IsLoggedIn() then
CombatStatus:Initialize()
else
CombatStatus:RegisterEvent(“PLAYER_LOGIN“)
end
The bulk of this code should seem familiar to you, but the section at the
bottom might seem a bit odd. As you’ve seen throughout the book, a number of
API functions don’t operate properly before the PLAYER_LOGIN event. Normally
you would just register for the PLAYER_LOGIN event, but when an addon is
flagged as load-on-demand it might be loaded after that event has already
fired. So you check the IsLoggedIn() API function to see if that event has
already passed, and if so, you call the initialization function directly.
As you add new functions to this addon, make sure to add them before the
initialization section at the bottom (beginning with the SetScript call), but
after the frame creation on the first line. Due to the complexity of this addon,
you will want to wait until the addon is finished before you test because some
functions reference others that are not yet defined.
Initializing CombatStatus
ThesetupforyouraddonwilloccurintheInitialize() method. There
you will set up the data tables, register for events, and create the dis-
play components of the addon. Add the following initialization function
to CombatStatus.lua. It’s not necessary to include the comments in your
version of the code, but that is entirely up to you.
function CombatStatus:Initialize()
self.combat_time = 0 -- The amount of time in combat
self.party_damage = {} -- Store the party’s DPS
Chapter 21 Responding to the Combat Log and Threat Information 403
self.party_heals = {} -- Store the party’s heals
self.pet_guids = {} -- Store GUID mappings for pets
-- This is a metatable that returns 0 for any non-set values. It will
-- allow us to use table entries without having to check them first
local zero_mt = {
__index = function(tbl, key)
return 0
end,
}
setmetatable(self.party_damage, zero_mt)
setmetatable(self.party_heals, zero_mt)
-- This table will be used to store snapshots of the data every few
-- seconds, allowing us to calculate DPS and HPS over a smaller
-- period of time. It will be indexed by unitid and each value will
-- be a table that returns 0 for default and holds the damage in the
-- damage field, and the heals in the heals field.
self.snapshots = {}
local emptytbl_mt = {
__index = function(tbl, key)
local new = setmetatable({}, zero_mt)
rawset(tbl, key, new)
return new
end,
}
setmetatable(self.snapshots, emptytbl_mt)
self.player_guid = UnitGUID(“player“)
self:RegisterEvent(“PARTY_MEMBERS_CHANGED“)
self:RegisterEvent(“UNIT_PET“)
self:RegisterEvent(“COMBAT_LOG_EVENT_UNFILTERED“)
self:RegisterEvent(“PLAYER_REGEN_ENABLED“)
self:RegisterEvent(“PLAYER_REGEN_DISABLED“)
self:CreateFrames()
self:UpdateFrame()
end
You define a number of entries in the frame’s table to store the state of
the addon. The first variable will allow you to track the amount of time the
player has been in combat. This allows you to take the total amount of damage
done, and divide it by the total amount of time spent in combat to get a unit’s
DPS. You store the damage and heals in separate tables (although you could
certainly conceive of different ways of doing this). You also need a place to
404 Part III Advanced Addon Techniques
store a mapping from pet GUID to owner GUID to ensure you can properly
handle pets.
You create a new metatable that returns 0 for any non-set values. This
allows you to avoid having to check if a value in the table is set before you
try to add anything to it. In the case of the damage tables, you can do the
following:
self.party_damage[guid] = self.party_damage[guid] + damageAmount
instead of:
local oldValue = self.party_damage[guid] or 0
self.party_damage[guid] = oldValue + damageAmount
It may be a minimal gain, but it’s also less prone to error. The snapshots
table is used to store periodic snapshots of the damage so you can display a
running average of everyone’s DPS. The table will be indexed by GUID and
the value is a table that contains two entries (health and heals) that both default
to 0. You use a metatable to create these tables automatically in the same way
you have the prior metatable default to 0.
Finally, you register for the following events:
PARTY_MEMBERS_CHANGEDUse this event to see when the composition of
the player’s party changes. This enables you to re-scan the pet mappings
and update the frame.
UNIT_PETThis event fires when a unit’s pet status changes, such as
when a Warlock or Hunter summons or dismisses a pet. This won’t cover
the cases where temporary pets are summoned; you’ll catch those in
another way.
COMBAT_LOG_EVENT_UNFILTEREDBecause this addon is all about collect-
ing information from the combat log, naturally you need to register for
this event. This event is likely to fire very frequently so you will want
to take precautions to ensure you don’t do anything computationally
intensive in response to it.
PLAYER_REGEN_DISABLEDLikewise, this event fires when the player
enters combat.
PLAYER_REGEN_ENABLEDThis event indicates that the player is no longer
in combat, so you can use it to swap between your two different
states.
Finally, you call the CreateFrame() method to create the status bars. Then
you call the UpdateFrame() method to actually run the update function. For
now, these methods don’t exist, but they will be filled in later.
Chapter 21 Responding to the Combat Log and Threat Information 405
Updating Pet Mappings
The strategy you’re going to take with pets is to map the pet GUID to the
owner GUID, so multiple pets get collapsed into a single amount of damage.
Add the following function that will take a unitID and update the GUID map
for that unit’s pets:
function CombatStatus:UpdatePets(unit)
local petUnit
if unit == “player“ then
petUnit = “pet“
else
petUnit = unit:gsub(“(party)(%d)“, “%1pet%2“)
end
if petUnit and UnitExists(petUnit) then
local guid = UnitGUID(unit)
local petGUID = UnitGUID(petUnit)
self.pet_guids[petGUID] = guid .. “pet“
end
end
To look up information about pets you need to use the unitID for the pet,
but you’re only given the unitID for the owner. For party members these IDs
are partypet1,partypet2,partypet3,andpartypet4.Youcanuseasimple
substitution using patterns to transform party1 into partypet1,asshownin
the preceding code.
You need to cover the special case of the player’s pet, which is just the
unitID ‘‘pet.’’ Once you have the correct unitID, you check to see if the unit
exists and if so you get the GUID. Rather than doing a direct mapping from
the pet GUID to the owner GUID, you do a mapping from the pet GUID to the
owner GUID with the string ‘‘pet’’ added to the end.
If you didn’t add this string you would need to store the pet’s damage in
another table (because the damage table is indexed by GUID). Otherwise, you
wouldnolongerbeabletodistinguishbetweenthepetsandtheoriginalunit
itself.
Storing Damage and Healing Information
You’re using the COMBAT_LOG_EVENT_UNFILTERED to get information about your
party’s damage and healing, so you need a function that extracts the right
information from the various possible events. Create the following function in
CombatStatus.lua:
local damageEvents = {
SWING_DAMAGE = true,
406 Part III Advanced Addon Techniques
RANGE_DAMAGE = true,
SPELL_DAMAGE = true,
SPELL_PERIODIC_DAMAGE = true,
DAMAGE_SHIELD = true,
DAMAGE_SPLIT = true,
}
local healEvents = {
SPELL_HEAL = true,
SPELL_PERIODIC_HEAL = true,
}
function CombatStatus:ProcessEntry(timestamp, combatEvent, srcGUID, i
srcName, srcFlags, destGUID, destName, destFlags, ...)
if damageEvents[combatEvent] then
local offset = combatEvent == “SWING_DAMAGE“ and 1 or 4
local amount, overkill, school, resisted, blocked, absorbed = i
select(offset, ...)
-- Check if this is a pet, and if so map the pet’s GUID to the party
-- member’s GUID using the mapping table.
if self.pet_guids[srcGUID] then
srcGUID = self.pet_guids[srcGUID]
end
self.party_damage[srcGUID] = self.party_damage[srcGUID] + amount
elseif healEvents[combatEvent] then
local amount, overhealing, absorbed = select(4, ...)
self.party_heals[srcGUID] = (self.party_heals[srcGUID] or 0) + i
(amount - overhealing)
elseif combatEvent == “SPELL_SUMMON“ then
-- A unit of ours has summoned a new pet/totem. Here we map the
-- new GUID to the party member’s with the string “pet“ added.
-- This way we can use a single table to store damage for all units
self.pet_guids[destGUID] = srcGUID .. “pet“
end
end
Because you are only concerned about events that are caused by damage or
events that are caused by healing you can use a lookup table to know whether
to continue processing. If the incoming event doesn’t match one of the entries
in the table, the function just returns.
If you look at the prefix/suffix information earlier in this chapter, you’ll see
that SWING_DAMAGE is the only damage event that doesn’t contain information
about the spell that caused the damage (because it’s caused by auto-attacking).
The first line of the damage event processing block sets a variable called offset
that is used to select() the right arguments from the arguments that were
passed in. If you’re on a SWING_DAMAGE event the offset is set to 1, otherwise
it’s set to 3.
Chapter 21 Responding to the Combat Log and Threat Information 407
You then select the amount of damage and other relevant information from
the arguments. You check the pet GUID mapping table to see if you need to
convert the pet GUID to the owner’s GUID. Then, you store the damage into
the damage table.
Heals are even easier because you don’t have to worry about pet’s healing
(for the purposes of this addon, we’re choosing not to track pet heals). You
don’t want to count overhealing, however, which is what happens when,
for example, a heal lands for 6000 healing but the target is only missing
3000 damage. In this case, the API will show 3000 overhealing, so you subtract
this from the amount healed.
The SPELL_SUMMON event indicates that someone in your party has sum-
moned a new pet (such as a totem or a druid’s treants). When this happens
and you don’t have the unitID, you just update the GUID mapping table
directly.
Taking ‘‘Snapshots’’ of Damage and Healing
Every few seconds you are going to take a snapshot of the current damage and
healing, allowing you to calculate averages over every few seconds rather than
only being able to display overall stats. Add the following function definition
to CombatStatus.lua:
local units = {“player“, “pet“, “party1“, “partypet1“, “party2“, “partypet2“, i
“party3“, “partypet3“, “party4“, “partypet4“}
function CombatStatus:TakeSnapshot()
-- This function loops through all the valid unit ids and stores
-- the current DPS or HPS so we can later subtract it.
for idx, unit in ipairs(units) do
local guid = UnitGUID(unit)
if guid then
if self.pet_guids[guid] then
guid = self.pet_guids[guid]
end
self.snapshots[guid].damage = self.party_damage[guid]
self.snapshots[guid].heals = self.party_heals[guid]
end
end
end
Because you need to loop over the unitIDs in both the update and the
snapshot functions, you create a table that has each of the unitIDs you’re
concerned with. For each unit, you look up the GUID and if it’s a known pet
GUID you translate it using your mapping table. Then you update the entry
in the snapshots table with the current damage and healing information.
408 Part III Advanced Addon Techniques
Writing an OnUpdate Function
You need a simple timer to handle the periodic updates to the damage and heal-
ing information. Add the following function definition to CombatStatus.lua:
local counter = 0
local throttle = 5.0
function CombatStatus:OnUpdate(elapsed)
counter = counter + elapsed
if counter >= throttle then
counter = 0
self:UpdateFrame(throttle)
self:TakeSnapshot()
end
end
Every five seconds when the frame is shown, the frame will be updated and
then a new snapshot will be taken. If you took the snapshot first, then everyone
would always show 0 dps because it would have nothing to compare against.
You pass the throttle argument to the update function, so it knows what
time period to divide the damage by.
Responding to Events
You need to glue everything together by responding to the events you have
registered for. Replace the OnEvent function with the following version:
function CombatStatus:OnEvent(event, ...)
if event == “COMBAT_LOG_EVENT_UNFILTERED“ then
-- Check to see if the source of the event is someone within the
-- circle of our party
local srcFlags = select(5, ...)
if bit.band(srcFlags, COMBATLOG_OBJECT_AFFILIATION_MASK) > i
COMBATLOG_OBJECT_AFFILIATION_PARTY then
return
end
self:ProcessEntry(...)
elseif event == “PARTY_MEMBERS_CHANGED“ then
for i = 1, GetNumPartyMembers() do
local unit = “party“ .. i
self:UpdatePets(unit)
end
if not self.in_combat then
self:UpdateFrame()
end
elseif event == “UNIT_PET“ then
local unit = ...
self:UpdatePets(unit)
Chapter 21 Responding to the Combat Log and Threat Information 409
elseif event == “PLAYER_REGEN_DISABLED“ then
self.in_combat = true
self.combat_start = GetTime()
counter = 0 -- Reset the OnUpdate counter
self:TakeSnapshot()
self:SetScript(“OnUpdate“, self.OnUpdate)
elseif event == “PLAYER_REGEN_ENABLED“ then
self.in_combat = false
self.combat_time = self.combat_time + GetTime() - self.combat_start
self:SetScript(“OnUpdate“, nil)
self:UpdateFrame()
elseif event == “PLAYER_LOGIN“ then
self:Initialize()
end
end
The different sections of this function are explained in the following section.
COMBAT_LOG_EVENT_UNFILTERED
The COMBAT_LOG_EVENT_UNFILTERED event will happen the most often, so you
want to ensure that it can be processed quickly. You put it at the top of the
event handler and only pass it to the processing function when the event
originates from an entity in the player’s party.
PARTY_MEMBERS_CHANGED
When the composition of the player’s party changes, you need to scan and
update the pet GUID mappings. Whenever the PARTY_MEMBERS_CHANGED event
fires, you loop through each of the party units and call the UpdatePets()
method, passing in the unit. Then, if the player isn’t currently in combat, you
update the frame. You don’t force an update when the player is in combat just
because you already know it’ll update when the OnUpdate triggers.
UNIT_PET
When a unit summons a pet, the UNIT_PET event will fire, with the first
argument being the unitID. As a result, you just call your UpdatePets()
function, passing in the unitID.
PLAYER_REGEN_DISABLED
You’ll need some way to track whether or not the player is in combat. You
could use the InCombatLockdown() function, but instead this addon uses the
PLAYER_REGEN_DISABLED event to set a flag on the frame. At the same time,
you also store the current time in the combat_start variable (so you can later
subtract it to get elapsed time). Then you take a snapshot to ensure you have
a point for comparison, and set the OnUpdate script so it will start triggering.
410 Part III Advanced Addon Techniques
PLAYER_REGEN_ENABLED
The PLAYER_REGEN_ENABLED event will fire when the player leaves combat, and
as a result the logic in this section is much the reverse of entering combat.
You turn the combat flag off, and update the total amount of combat time by
subtracting the current time from the start time. Next you clear the OnUpdate
function and update the frame, which will show the total stats instead of the
rolling average.
Creating the Frame Display
As an initial example, the display for this addon will be series of text strings
that contain the damage and healing information. Eventually, you’ll want to
expand it to use status bars instead of text strings. Create your CreateFrames()
function:
function CombatStatus:CreateFrames()
self:ClearAllPoints()
self:SetPoint(“TOP“, MinimapCluster, “BOTTOM“, 0, -15)
self:SetWidth(300)
self:SetHeight(150)
self.rows = {}
fori=1,10do
local row = self:CreateFontString(nil, “OVERLAY“, i
“GameFontHighlight“)
row:SetText(“Blah“)
self.rows[i] = row
if i == 1 then
row:SetPoint(“TOPLEFT“, 0 ,0)
else
row:SetPoint(“TOPLEFT“, self.rows[i-1], “BOTTOMLEFT“, 0, 0)
end
end
end
The frame is anchored directly below the minimap cluster and consists of 10
different font strings.
Updating the Frame Display
The actual calculations are accomplished in the UpdateFrame() method. Add
this method to your file anywhere below the TakeSnapshot() method, because
it uses the units table defined just before that function.
function CombatStatus:UpdateFrame(elapsed)
for idx, unit in ipairs(units) do
local row = self.rows[idx]
Chapter 21 Responding to the Combat Log and Threat Information 411
if UnitExists(unit) then
local guid = UnitGUID(unit)
if self.pet_guids[guid] then
guid = self.pet_guids[guid]
end
local dps, hps
if elapsed and elapsed > 0 then
-- We are being called from the OnUpdate so we compare
-- against the snapshot rather than calculating the
-- total DPS and HPS
dps = (self.party_damage[guid] - self.snapshots[guid].damage) i
/ elapsed
hps = (self.party_heals[guid] - self.snapshots[guid].heals) i
/ elapsed
elseif self.combat_time > 0 then
dps = self.party_damage[guid] / self.combat_time
hps = self.party_heals[guid] / self.combat_time
else
dps=0
hps=0
end
-- Actually update the frame with the new values here
local name = UnitName(unit)
local dpstext = self:ShortNum(dps)
local hpstext = self:ShortNum(hps)
row:SetFormattedText(“[%s] DPS: %s, Heal %s“, name, dpstext, i
hpstext)
row:Show()
else
row:Hide()
end
end
end
The overall strategy here is to loop over each of the unitIDs and check to
see if the unit exists. If so, you fetch the GUID, translating it to a pet GUID if
necessary. Then you have two different sets of calculations. If the elapsed value
it set, it indicates the amount of time that has passed since the last snapshot.
In this case, you divide the difference between the current damage and the
snapshot by the elapsed time. Otherwise, you take the total damage and divide
by the total time in combat.
You use a utility function you’re going to write to convert the numeric DPS
into a shorter version. Finally, you set the text string to display the heal per
second and damage per second. Define the ShortNum() method:
function CombatStatus:ShortNum(num)
local large = num > 1000
412 Part III Advanced Addon Techniques
return string.format(“%.2f%s“, large and (num / 1000) or num, i
large and “k“ or ““)
end
This function takes in a number and if it’s greater than 1000, converts it to
a shorter form. This function will turn the damage 3337 into 3.34k, making it
much easier to read and compare.
Future Additions
In its current form, CombatStatus is very primitive. Instead of showing status
bars (or some other, flashier way of displaying the data), it uses simple
formatted font strings. There are blank spaces left when units don’t exist and
it’s not customizable in any way. Think about a few enhancements you might
want for this basic addon, and consider releasing your own updated version!
Summary
This chapter introduced the combat log event system, including how to
distinguish between the different combat events. You learned the different
prefixes and suffixes that make up different events, including the arguments
that differ between them. You created an addon that can track the damage and
healing of your party both as a running average and total average. The next
chapter shows you how to create scroll frames for displaying your data.
CHAPTER
22
Creating Scroll Frames
When creating a custom user interface, you may have a need to display data
that is too large for a reasonably sized window. World of Warcraft allows you
to create frames that can scroll both horizontally and vertically, giving you
more flexibility in the display of your data. This chapter shows you how to
create two different types of scroll frames that are used throughout the default
user interface.
AScrollFrame is used to allow horizontal and vertical smooth scrolling of
data that is too large for the containing frame. In the default user interface,
the Quest Log uses a scroll frame when the quest description is too long for
the window (see Figure 22-1). This type of scroll frame allows for smooth
pixel-by-pixel scrolling of the contents.
A faux scroll frame is, as the name suggests, a way to simulate a scroll frame
without actually using one. The Auction House uses this technique to display
a list of auctions, shown in Figure 22-2. Because each row of the listing has the
same size, only enough rows are created to show a single page of the listing
instead of creating one for every single item.
As the user scrolls through the listing, the rows are updated to display
different elements of the list. For certain applications this method is more
efficient than trying to create a set of frames for every single row of the listing.
The inner workings of a scroll frame are very complex, so suffice it to say
that the user interface first has to render the contents, and then render the
scroll frame to contain it. This can be very inefficient, and you should avoid
using scroll frames in tense situations, such as combat.
This chapter first shows you how to create actual scroll frames, and then
introduces the basics of creating FauxScrollFrames.
413
414 Part III Advanced Addon Techniques
Scroll frame Scroll bar
Figure 22-1: Quest Log scroll frame not scrolled (left) and scrolled (right), showing more
of the quest text.
Figure 22-2: Auction House using a FauxScrollFrame
Using Scroll Frames
A scroll frame comprises the scrolling frame itself (the frame actually doing
the visual clipping of its contents) and the scroll child (a frame that contains
the contents). The scroll child can be a frame, a button or any other frame
Chapter 22 Creating Scroll Frames 415
type. Although the scroll frame provides an API for scrolling horizontally and
vertically, it does not provide any scroll bars on its own.
You can experiment with scroll frames by creating a new addon skeleton
called ScrollFrameTest, so you have a place to put the test code for this
chapter. Create ScrollFrameTest.toc with the following contents:
## Interface: 30300
## Title: ScrollFrameTest
## Notes: Test addon for scroll frames
ScrollFrameTest.xml
ScrollFrameTest.lua
Next, create the basic frame definition within ScrollFrameTest.xml:
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<ScrollFrame name=“ScrollFrameTest“>
<Size x=“150“ y=“150“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Layers>
<Layer level=“BACKGROUND“>
<Texture setAllPoints=“true“>
<Color r=“0.0“ g=“0.0“ b=“0.0“/>
</Texture>
</Layer>
</Layers>
</ScrollFrame>
</Ui>
This definition creates a 150x150 frame in the center of the screen with a
black background.
Adding a Scroll Child
The actual contents of the frame are defined within the <ScrollChild> element
when using XML, or set with the SetScrollChild() method when using Lua.
Add the following section to ScrollFrameTest.xml immediately after the
</Layers> tag:
<ScrollChild>
<Frame>
<Size x=“250“ y=“250“/>
<Layers>
<Layer level=“ARTWORK“>
<Texture file=“Interface\Icons\Spell_Shadow_DemonicFortitude“>
416 Part III Advanced Addon Techniques
<Size x=“100“ y=“100“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
</Texture>
</Layer>
</Layers>
</Frame>
</ScrollChild>
The <ScrollChild> element should contain exactly one frame (or frame
derivative) that contains the contents of the scroll frame. This child frame can
be any size, but it will be visually clipped to the size of the <ScrollFrame>
element. As a matter of fact, the horizontal and vertical scroll ranges are
defined by the size of this child frame.
Load the game and you should see an image in the center of your screen
similar to that shown in Figure 22-3.
Figure 22-3: ScrollFrameTest
Manipulating a ScrollFrame
Like any other specific type of frame, a ScrollFrame has different methods
and handler scripts available. For example, the following methods can be used
on scroll frames:
GetHorizontalScroll()Returns the current scroll value of the hori-
zontal scroll component.
GetVerticalScroll()Returns the current scroll value of the vertical
scroll component.
SetHorizontalScroll()Sets the scroll value of the horizontal scroll
component.
SetVerticalScroll()Sets the scroll value of the vertical scroll compo-
nent.
GetHorizontalScrollRange()Returns the maximum scroll range for
the horizontal scroll component.
Chapter 22 Creating Scroll Frames 417
GetVerticalScrollRange()Returns the maximum scroll range for the
vertical scroll component.
UpdateScrollChildRect()Updates the virtual size of the scroll child.
This function should be called when the contents of the scroll frame are
changed.
You can use these methods to center the image, using the following scripts
in-game:
/run ScrollFrameTest:SetHorizontalScroll(-50)
/run ScrollFrameTest:SetVerticalScroll(50)
Note that the horizontal scroll requires a negative value to scroll the child to
the right, whereas vertical scroll takes a positive number to scroll the child up.
This is consistent with the way coordinates in the user interface work, where
(0,0) is the bottom-left corner of the screen. Figure 22-4 shows the frame when
adjusted using these commands.
Figure 22-4: ScrollFrameTest scrolled 50 pixels to the left and 50 pixels up.
Adding Scroll Bars
As you have seen, creating a scroll frame is simple, but isn’t very helpful to
your users if they have to use slash commands to scroll the frame. This section
shows you an easy way to create a scroll bar using the Slider frame type.
Add the following to ScrollFrameTest.xml,afterthe</Layers> tag and
before the <ScrollChild> tag. The particular order is important if you are
validating your XML file, since the schema requires any sub-frames to be
defined before the scroll child.
<Frames>
<Slider name=“ScrollFrameTest_HSlider“ orientation=“HORIZONTAL“
minValue=“0“ maxValue=“100“ defaultValue=“0“ valueStep=“1“>
<Size x=“150“ y=“25“/>
<Anchors>
<Anchor point=“TOP“ relativePoint=“BOTTOM“ i
relativeTo=“ScrollFrameTest“/>
</Anchors>
418 Part III Advanced Addon Techniques
<Scripts>
<OnValueChanged>
ScrollFrameTest:SetHorizontalScroll(-1 * self:GetValue())
</OnValueChanged>
</Scripts>
<ThumbTexture name=“$parentThumbTexture“
file=“Interface\Buttons\UI-ScrollBar-Knob“>
<Size x=“25“ y=“25“/>
</ThumbTexture>
</Slider>
<Slider name=“ScrollFrameTest_VSlider“ orientation=“VERTICAL“
minValue=“0“ maxValue=“100“ defaultValue=“0“ valueStep=“1“>
<Size x=“25“ y=“150“/>
<Anchors>
<Anchor point=“LEFT“ relativePoint=“RIGHT“ i
relativeTo=“ScrollFrameTest“/>
</Anchors>
<Scripts>
<OnValueChanged>
ScrollFrameTest:SetVerticalScroll(self:GetValue())
</OnValueChanged>
</Scripts>
<ThumbTexture name=“$parentThumbTexture“
file=“Interface\Buttons\UI-ScrollBar-Knob“>
<Size x=“25“ y=“25“/>
</ThumbTexture>
</Slider>
</Frames>
These two XML definitions create two sliders with a range between 0
and 100, because the child frame is exactly 100 pixels larger than the scroll
frame in either dimension. When the sliders are moved, the horizontal or
vertical scroll is updated on the scroll frame. These simple scroll bars use
the UI-ScrollBar-Knob graphic for the slider ‘‘thumb’’ graphic, and could be
extended to use the border and backgrounds from those scroll bars, as well.
Figure 22-5 shows the scroll frame operating in-game.
Figure 22-5: ScrollFrameTest scroll frame, with scroll bars.
Chapter 22 Creating Scroll Frames 419
Now the frame can also be adjusted via the sliders, using the SetValue()
method, as in the following commands:
/run ScrollFrameTest_HSlider:SetValue(50)
/run ScrollFrameTest_VSlider:SetValue(50)
Creating Faux Scroll Frames
A faux scroll frame is a bit more complex to make because it must be tailored
to the specific need. For example, you typically create a template and then a
series of entries to make a single page. This section shows you how to create a
line of icons onscreen that can be scrolled through in order to display all valid
macro icons for selection. The API functions used here are the following:
GetNumMacroIcons()Returns the number of available macro icons.
GetMacroIconInfo(index)Returns the texture for the selected macro
index.
This addon displays six icons side by side, and the slider is used to scroll
between the available icons. Begin by creating an addon skeleton called
MacroIconTest, and putting the following into MacroIconTest.toc:
## Interface: 30300
## Title: MacroIconTest
## Notes: Test addon for a faux scroll frame
MacroIconTest.lua
MacroIconTest.xml
Create MacroIconTest.xml with the following contents:
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Button name=“MacroIconTest_IconTemplate“ virtual=“true“>
<Size x=“32“ y=“32“/>
<NormalTexture name=“$parentIcon“ setAllPoints=“true“/>
<HighlightTexture alphaMode=“ADD
file=“Interface\Buttons\ButtonHilight-Square“/>
</Button>
</Ui>
This simple XML template is used to create each of the icon slots. It defines a
default texture, as well as a highlight texture to give a bit more visual feedback.
InsertthefollowingXMLbeforethe</Ui> tag to create a set of icons:
<Frame name=“MacroIconTest“>
<Size x=“192“ y=“32“/>
<Anchors>
420 Part III Advanced Addon Techniques
<Anchor point=“CENTER“/>
</Anchors>
<Frames>
<Button name=“$parentIcon1“ inherits=“MacroIconTest_IconTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“/>
</Anchors>
</Button>
<Button name=“$parentIcon2“ inherits=“MacroIconTest_IconTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ i
relativeTo=“$parentIcon1“/>
</Anchors>
</Button>
<Button name=“$parentIcon3“ inherits=“MacroIconTest_IconTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ i
relativeTo=“$parentIcon2“/>
</Anchors>
</Button>
<Button name=“$parentIcon4“ inherits=“MacroIconTest_IconTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ i
relativeTo=“$parentIcon3“/>
</Anchors>
</Button>
<Button name=“$parentIcon5“ inherits=“MacroIconTest_IconTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ i
relativeTo=“$parentIcon4“/>
</Anchors>
</Button>
<Button name=“$parentIcon6“ inherits=“MacroIconTest_IconTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ i
relativeTo=“$parentIcon5“/>
</Anchors>
</Button>
</Frames>
</Frame>
If you jump into the game at this point, you’ll have an invisible set of boxes
that can be moused over (the highlight texture will still show) but that don’t
actually display anything. Jump to MacroIconTest.lua and add the following
function:
function MacroIconTest_UpdateIcons(startIcon)
local name = “MacroIconTestIcon“
for i=1,6 do
local texture = GetMacroIconInfo(startIcon + (i - 1))
Chapter 22 Creating Scroll Frames 421
local button = getglobal(name .. i)
button:SetNormalTexture(texture)
end
end
This function accepts a single argument, namely the index of the icon
that should be displayed first. It then loops through the six different icon
buttons and changes their texture accordingly. The loop assumes the first icon
is numbered 1, because the GetMacroIconInfo() function makes the same
assumption.
TIP Not all data is available immediately within the game client. For example,
the number of icons and the texture information about each macro icon isn’t
available until after the client has been partially initialized. Generally, this
information is available after the PLAYER_LOGIN event, which is fired just before
the client begins displaying the 3-D world. Some functions may need to be delayed
until after this event to work properly.
Add the following behavior scripts to the MacroIconTest frame by putting
the following section immediately after its </Frames> tag:
<Scripts>
<OnLoad>
self:RegisterEvent(“PLAYER_LOGIN“)
</OnLoad>
<OnEvent>
if event == “PLAYER_LOGIN“ then
GetNumMacroIcons()
MacroIconTest_UpdateIcons(1)
end
</OnEvent>
</Scripts>
Here you register for the PLAYER_LOGIN event, and when that event
fires, the OnEvent script calls GetNumMacroIcons(), and then calls the
MacroIconTest_UpdateIcons() function to update the icon display. When
guild banks were introduced, the macro icon system was changed so icon
information isn’t available until the GetNumMacroIcons() function has been
called at least once, hence the call here. Load the game client, and you should
see something like that shown in Figure 22-6 in the center of your screen.
Figure 22-6: MacroIconTest frame
422 Part III Advanced Addon Techniques
Test the update function by running some of the following macros:
/run MacroIconTest_UpdateIcons(15)
/run MacroIconTest_UpdateIcons(180)
/run MacroIconTest_UpdateIcons(-1)
Notice that in the last example, rather than an error the first two icons are
shown as blank.
Adding Scroll Bars
As in the previous example, a slider can be used to scroll through the list of
icons. Add the following to your MacroIconTest.xml file after the </Frame>
tag from the main frame:
<Slider name=“MacroIconTest_HSlider“ orientation=“HORIZONTAL“>
<Size y=“25“/>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“BOTTOMLEFT“ i
relativeTo=“MacroIconTest“/>
<Anchor point=“TOPRIGHT“ relativePoint=“BOTTOMRIGHT“
relativeTo=“MacroIconTest“/>
</Anchors>
<Backdrop edgeFile=“Interface\Buttons\UI-SliderBar-Border“
bgFile=“Interface\Buttons\UI-SliderBar-Background“ tile=“true“>
<EdgeSize>
<AbsValue val=“8“/>
</EdgeSize>
<TileSize>
<AbsValue val=“8“/>
</TileSize>
<BackgroundInsets>
<AbsInset left=“3“ right=“3“ top=“6“ bottom=“6“/>
</BackgroundInsets>
</Backdrop>
<ThumbTexture name=“$parentThumbTexture“
file=“Interface\Buttons\UI-ScrollBar-Knob“>
<Size x=“25“ y=“25“/>
</ThumbTexture>
</Slider>
This creates a slider bar with a backdrop and border to make it look a bit
more like a scroll bar. Add the scripts section to the slider by putting the
following after the </Backdrop> tag and before the definition of the thumb
texture:
<Scripts>
<OnLoad>
local max = GetNumMacroIcons()
Chapter 22 Creating Scroll Frames 423
self:SetMinMaxValues(1, max - 5)
self:SetValueStep(1.0)
self:SetValue(1)
</OnLoad>
<OnValueChanged>
MacroIconTest_UpdateIcons(value)
</OnValueChanged>
</Scripts>
The resulting addon is shown in Figure 22-7, including the scroll bar with
border and background.
Figure 22-7: MacroIconTest addon showing various macro icons
Scrolling with the Mouse Wheel
As an extra method of scrolling the icons, you can add support for scrolling
with the mouse wheel. This involves setting an OnMouseWheel script. Add the
following to the <Scripts> section of the MacroIconTest frame (not the slider):
<OnMouseWheel>
MacroIconTest_OnMouseWheel(self, delta)
</OnMouseWheel>
Then add this function to MacroIconTest.lua:
function MacroIconTest_OnMouseWheel(self, delta)
local current = MacroIconTest_HSlider:GetValue()
if (delta < 0) and (current < GetNumMacroIcons()) then
MacroIconTest_HSlider:SetValue(current + 1)
elseif (delta > 0) and (current > 1) then
MacroIconTest_HSlider:SetValue(current - 1)
end
end
This function definition just piggybacks onto the slider bar’s min and max
values to ensure it doesn’t go outside those boundaries. You should now be
able to scroll the frame using both the slider and the mouse wheel.
Problems with Slider Precision
You may notice that if you scroll using slash commands or the mouse wheel,
you can scroll through the icons one-by-one. If you try to use the slider instead,
424 Part III Advanced Addon Techniques
you can’t really tell how many icons are scrolling on each step. That’s because
there are more than a thousand icons to be displayed, and the slider widget
only has so much precision when working with the mouse.
You could fix this by changing the step value for the slider. In this case,
change it to 3, so the slider will move in steps of 3. Unfortunately, if you change
the precision of the slider, the mouse wheel can no longer scroll icon-by-icon.
You may never run into this issue, but here’s the change you would make to
allow this (altered lines are highlighted):
<OnLoad>
local max = GetNumMacroIcons()
self:SetMinMaxValues(1, max - 5)
self:SetValueStep(3.0)
self:SetValue(1)
</OnLoad>
Summary
A visual scroll frame is a smooth, pixel-by-pixel scroll frame that can be used
to display contents that are too large for the parent window. Scroll frames of
this nature are used in the default user interface in the Quest Log, and within
the edit box in the macro window.
A faux scroll frame uses a set number of frames to display a list of rows
or columns by changing offsets using the scroll bar. These scroll frames don’t
change visually when you scroll through them; rather, they redraw the rows
with different information. These pseudo scroll frames are used in the Auction
House, Friends list, and several other places in the default user interface.
The Code
ScrollFrameTest
ScrollFrameTest.toc
## Interface: 30300
## Title: ScrollFrameTest
## Notes: Test addon for scroll frames
ScrollFrameTest.xml
ScrollFrameTest.lua
ScrollFrameTest.xml
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
Chapter 22 Creating Scroll Frames 425
http://wowprogramming.com/FrameXML/UI.xsd“>
<ScrollFrame name=“ScrollFrameTest“>
<Size x=“150“ y=“150“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Layers>
<Layer level=“BACKGROUND“>
<Texture setAllPoints=“true“>
<Color r=“0.0“ g=“0.0“ b=“0.0“/>
</Texture>
</Layer>
</Layers>
<Frames>
<Slider name=“ScrollFrameTest_HSlider“ i
orientation=“HORIZONTAL“
minValue=“0“ maxValue=“100“ defaultValue=“0“ valueStep=“1“>
<Size x=“150“ y=“25“/>
<Anchors>
<Anchor point=“TOP“ relativePoint=“BOTTOM“ i
relativeTo=“ScrollFrameTest“/>
</Anchors>
<Scripts>
<OnValueChanged>
ScrollFrameTest:SetHorizontalScroll(-1 * i
self:GetValue())
</OnValueChanged>
</Scripts>
<ThumbTexture name=“$parentThumbTexture“
file=“Interface\Buttons\UI-ScrollBar-Knob“>
<Size x=“25“ y=“25“/>
</ThumbTexture>
</Slider>
<Slider name=“ScrollFrameTest_VSlider“ orientation=“VERTICAL“
minValue=“0“ maxValue=“100“ defaultValue=“0“ valueStep=“1“>
<Size x=“25“ y=“150“/>
<Anchors>
<Anchor point=“LEFT“ relativePoint=“RIGHT“ i
relativeTo=“ScrollFrameTest“/>
</Anchors>
<Scripts>
<OnValueChanged>
ScrollFrameTest:SetVerticalScroll(self:GetValue())
</OnValueChanged>
</Scripts>
<ThumbTexture name=“$parentThumbTexture“
file=“Interface\Buttons\UI-ScrollBar-Knob“>
<Size x=“25“ y=“25“/>
</ThumbTexture>
</Slider>
426 Part III Advanced Addon Techniques
</Frames>
<ScrollChild>
<Frame>
<Size x=“250“ y=“250“/>
<Layers>
<Layer level=“ARTWORK“>
<Texture i
file=“Interface\Icons\Spell_Shadow_DemonicFortitude“>
<Size x=“100“ y=“100“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
</Texture>
</Layer>
</Layers>
</Frame>
</ScrollChild>
</ScrollFrame>
</Ui>
MacroIconTest
MacroIconTest.toc
## Interface: 30200
## Title: MacroIconTest
## Notes: Test addon for a faux scroll frame
MacroIconTest.lua
MacroIconTest.xml
MacroIconTest.lua
function MacroIconTest_UpdateIcons(startIcon)
local name = “MacroIconTestIcon“
for i=1,6 do
local texture = GetMacroIconInfo(startIcon + (i - 1))
local button = getglobal(name .. i)
button:SetNormalTexture(texture)
end
end
function MacroIconTest_OnMouseWheel(self, delta)
local current = MacroIconTest_HSlider:GetValue()
if (delta < 0) and (current < GetNumMacroIcons()) then
MacroIconTest_HSlider:SetValue(current + 1)
elseif (delta > 0) and (current > 1) then
MacroIconTest_HSlider:SetValue(current - 1)
end
end
Chapter 22 Creating Scroll Frames 427
MacroIconTest.xml
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Button name=“MacroIconTest_IconTemplate“ virtual=“true“>
<Size x=“32“ y=“32“/>
<NormalTexture name=“$parentIcon“ setAllPoints=“true“/>
<HighlightTexture alphaMode=“ADD“ i
file=“Interface\Buttons\ButtonHilight-Square“/>
</Button>
<Frame name=“MacroIconTest“>
<Size x=“192“ y=“32“/>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Frames>
<Button name=“$parentIcon1“ i
inherits=“MacroIconTest_IconTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“/>
</Anchors>
</Button>
<Button name=“$parentIcon2“ i
inherits=“MacroIconTest_IconTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ i
relativeTo=“$parentIcon1“/>
</Anchors>
</Button>
<Button name=“$parentIcon3“
inherits=“MacroIconTest_IconTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ i
relativeTo=“$parentIcon2“/>
</Anchors>
</Button>
<Button name=“$parentIcon4“ i
inherits=“MacroIconTest_IconTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ i
relativeTo=“$parentIcon3“/>
</Anchors>
</Button>
<Button name=“$parentIcon5“ i
inherits=“MacroIconTest_IconTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ i
relativeTo=“$parentIcon4“/>
428 Part III Advanced Addon Techniques
</Anchors>
</Button>
<Button name=“$parentIcon6“ i
inherits=“MacroIconTest_IconTemplate“>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“TOPRIGHT“ i
relativeTo=“$parentIcon5“/>
</Anchors>
</Button>
</Frames>
<Scripts>
<OnLoad>
self:RegisterEvent(“PLAYER_LOGIN“)
</OnLoad>
<OnEvent>
if event == “PLAYER_LOGIN“ then
GetNumMacroIcons()
MacroIconTest_UpdateIcons(1)
end
</OnEvent>
<OnMouseWheel>
MacroIconTest_OnMouseWheel(self, delta)
</OnMouseWheel>
</Scripts>
</Frame>
<Slider name=“MacroIconTest_HSlider“ orientation=“HORIZONTAL“>
<Size y=“25“/>
<Anchors>
<Anchor point=“TOPLEFT“ relativePoint=“BOTTOMLEFT“ i
relativeTo=“MacroIconTest“/>
<Anchor point=“TOPRIGHT“ relativePoint=“BOTTOMRIGHT“ i
relativeTo=“MacroIconTest“/>
</Anchors>
<Backdrop edgeFile=“Interface\Buttons\UI-SliderBar-Border“
bgFile=“Interface\Buttons\UI-SliderBar-Background“
tile=“true“>
<EdgeSize>
<AbsValue val=“8“/>
</EdgeSize>
<TileSize>
<AbsValue val=“8“/>
</TileSize>
<BackgroundInsets>
<AbsInset left=“3“ right=“3“ top=“6“ bottom=“6“/>
</BackgroundInsets>
</Backdrop>
<Scripts>
<OnLoad>
local max = GetNumMacroIcons()
self:SetMinMaxValues(1, max - 5)
Chapter 22 Creating Scroll Frames 429
self:SetValueStep(1.0)
self:SetValue(1)
</OnLoad>
<OnValueChanged>
MacroIconTest_UpdateIcons(value)
</OnValueChanged>
</Scripts>
<ThumbTexture name=“$parentThumbTexture“
file=“Interface\Buttons\UI-ScrollBar-Knob“>
<Size x=“25“ y=“25“/>
</ThumbTexture>
</Slider>
</Ui>
CHAPTER
23
Creating Dropdown Menus
Dropdown menus are used throughout the default user interface to pro-
vide the user with a list of selectable items. Some menus, such as the
menu that appears when you right-click your player frame (shown in
Figure 23-1), are used to provide a list of actions or configuration options
based on context. Other menus have artwork that makes them appear as more
standard dropdown-style menus, such as the dropdown used for the column
selection in the Who list panel, shown in Figure 23-2.
At a first glance, the system to create these dropdowns may seem rather
complex. This chapter helps to demystify the dropdown system in World of
Warcraft, showing you how to create them and make them work for your
addons.
Creating a Basic Dropdown
Creating a dropdown involves four major steps. Luckily, Blizzard provides a
robust set of templates and functions that make creating them fairly easy. This
section leads you through these steps:
1. Adding a button that can be clicked to show the dropdown menu.
This may be a button that already exists in your addon or something
entirely new.
2. Creating a new frame that inherits Blizzard’s UIDropDownMenuTemplate
template. It is not strictly necessary to create your own frame, but this
method allows you to ensure no other addons will accidentally alter your
dropdown.
431
432 Part III Advanced Addon Techniques
Figure 23-1: Dropdown menu displayed when right-clicking on the player frame
Figure 23-2: Column dropdown in the Who list panel
3. Initializing the dropdown menu once it has been created.
4. Writing code that causes a click on the button to toggle the display of the
dropdown menu.
For this example, you need to create a new addon called DropDownTest. Cre-
ate the basic addon skeleton including DropDownTest.toc,DropDownTest.lua,
and DropDownTest.xml.
Adding a Toggle Button
Using the Blizzard template GameMenuButtonTemplate, create a button by
adding the following code to DropDownTest.xml:
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Button name=“DropDownTest_Button“ inherits=“GameMenuButtonTemplate“ i
parent=“UIParent“ text=“DropDownTest“>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Scripts>
<OnClick>
DropDownTest_ButtonOnClick(self, button, down)
</OnClick>
Chapter 23 Creating Dropdown Menus 433
</Scripts>
</Button>
</Ui>
To make a quick and easy button, this code uses the GameMenuButton
Template. The text is set using the XML attribute, and the new button is
anchored to the center of the user interface. When the button is clicked,
it calls the DropDownTest_ButtonOnClick() function and passes the proper
arguments.
Creating a Dropdown Frame
The default Blizzard interface uses templates for its dropdown menus and, as
a result, you can re-use the templates as a basis for your own menus. Add the
following frame definition to DropDownTest.xml:
<Frame name=“DropDownTest_DropDown“ inherits=“UIDropDownMenuTemplate“
frameStrata=“FULLSCREEN_DIALOG“>
<Scripts>
<OnLoad>
DropDownTest_DropDownOnLoad(self)
</OnLoad>
</Scripts>
</Frame>
This frame simply inherits from the given template and sets the frameStrata
to be DIALOG_FULLSCREEN. This allows the dropdown menu to be used on
another frame that is already set to display on the full screen frame strata.
When the frame is first created, DropDownTest_DropDownOnLoad() is called to
handle the initialization of the dropdown menu.
Initializing the Dropdown
Two things need to happen when you are initializing a dropdown menu.
First, you must define a function that will be responsible for describing the
actual buttons and adding them to the menu. Second, you must call the global
UIDropDownMenu_Initialize() function to do some setup and accounting on
the frame.
Adding Buttons to the Dropdown
This initialization function is called by the default user interface to set up
the actual buttons that appear within thedropdownmenu.Thefunctionis
passed the dropdown frame as the first argument, and a second argument,
level, indicates what level of the dropdown is being displayed (for multilevel
menus). This example does not use this argument because it will only contain
three items on the same level; multilevel menus are covered later in this
chapter.
434 Part III Advanced Addon Techniques
Add the following function to your DropDownTest.lua file:
function DropDownTest_InitializeDropDown(self, level)
-- Create a table to use for button information
local info = UIDropDownMenu_CreateInfo()
-- Create a title button
info.text = “DropDown Test“
info.isTitle = 1
UIDropDownMenu_AddButton(info)
-- Create a normal button
info = UIDropDownMenu_CreateInfo()
info.text = “Sample Item 1“
UIDropDownMenu_AddButton(info)
-- Create another normal button
info = UIDropDownMenu_CreateInfo()
info.text = “Sample Item 2“
UIDropDownMenu_AddButton(info)
end
The UIDropDownMenu_CreateInfo() function here is used to get an empty
info table to be filled with button attributes and eventually passed into
UIDropDownMenu_AddButton(). Internally this function re-uses tables to pre-
vent excessive memory usage for larger menus.
Calling UIDropDownMenu_Initialize()
To tell the user interface what initialization function should be called when
the dropdown is shown, you must call UIDropDownMenu_Initialize().This
function takes in the dropdown frame as the first argument, and the initial-
ization function as the second. Call this function by adding the following to
DropDownTest.lua:
function DropDownTest_DropDownOnLoad(self)
UIDropDownMenu_Initialize(self, DropDownTest_InitializeDropDown)
end
Your initialization function will now be called each time the menu is opened,
and again every time the state of the menu changes (for example when you
check an option, or open a submenu).
Toggling the Dropdown Menu
The final step is actually opening the dropdown menu when the user clicks the
button you’ve created. The Blizzard template code defines a toggle function,
called ToggleDropDownMenu(), that allows you do this, as well as specify some
Chapter 23 Creating Dropdown Menus 435
basic positioning information. The function takes eight possible arguments,
but only the first six are typically used:
level (number)The initial level to display. This number is passed
directly to the initialization function.
valueA value used to set the global variable UIDROPDOWNMENU_MENU_
VALUE, which is used primarily in multilevel menus. This is discussed in
detail later in this chapter.
dropDownFrameThe actual dropdown frame to display.
anchorName (string)The name of the frame to which the dropdown
should be anchored. This can also be the string cursor, in which case the
dropdown is anchored to the cursor position at the moment this function
is called.
xOffset (number)A horizontal offset in units for the dropdown menu.
yOffset (number)A vertical offset in units for the dropdown menu.
Add the following function to DropDownTest.lua to call ToggleDropDown
Menu() when the test button is clicked:
function DropDownTest_ButtonOnClick(self, button, down)
local name = self:GetName()
ToggleDropDownMenu(1, nil, DropDownTest_DropDown, name, 0, 0)
end
Because this example displays only one level of the menu, the function
passes 1as the level and doesn’t include a menu value. The dropdown will be
anchored to the button itself, with no offset from the default location.
Testing the Dropdown
Log in to World of Warcraft with the DropDownTest addon enabled; a game
button should display in the center of your screen. Click the button and you
should see the dropdown menu shown in Figure 23-3.
Figure 23-3: Dropdown menu created by the DropDownTest addon
436 Part III Advanced Addon Techniques
The example menu won’t do anything at the moment, but later in this
chapter you learn how to make the menu elements functional so they can be
used for configuration and other purposes. By default, the menu will timeout
after a certain period of inactivity, and clicking the test button while the menu
is open closes it outright.
Creating Multilevel Dropdowns
Creating a multilevel dropdown menu is straightforward once you understand
how a dropdown menu is created and initialized. In particular, the first
argument passed to the initialization function is a numeric value, the level of
the dropdown being displayed.
Consider a dropdown with two submenus called Alpha and Beta. Assume
each menu has distinct items that will be displayed. Because the root level
of the menu is 1, the level for both Alpha and Beta is 2.Ifeachofthemhad
submenus, they would be level 3, and so on. To differentiate between Alpha
and Beta, you will set a value element in the button table.
Rewrite the DropDownTest_InitializeDropDown() function in your test
addon, as follows:
function DropDownTest_InitializeDropDown(self, level)
if level == 1 then
local info = UIDropDownMenu_CreateInfo()
info.text = “DropDown Test“
info.isTitle = true
UIDropDownMenu_AddButton(info, level)
info = UIDropDownMenu_CreateInfo()
info.text = “Alpha Submenu“
info.hasArrow = true
info.value = “Alpha“
UIDropDownMenu_AddButton(info, level)
info = UIDropDownMenu_CreateInfo()
info.text = “Beta Submenu“
info.hasArrow = true
info.value = “Beta“
UIDropDownMenu_AddButton(info, level)
elseif (level == 2) and (UIDROPDOWNMENU_MENU_VALUE == “Alpha“) then
local info = UIDropDownMenu_CreateInfo()
info.text = “Alpha Sub-item 1“
UIDropDownMenu_AddButton(info, level)
elseif (level == 2) and (UIDROPDOWNMENU_MENU_VALUE == “Beta“) then
local info = UIDropDownMenu_CreateInfo()
info.text = “Beta Sub-item 1“
Chapter 23 Creating Dropdown Menus 437
UIDropDownMenu_AddButton(info, level)
end
end
You’ll notice quite a few differences from the original function, namely the
use of the hasArrow and value attributes in some of the button tables. hasArrow
tells the template code to treat the button as a menu header and to display the
arrow graphic. The value attribute is used to distinguish between different
submenus.
In the initialization function, if the level is 2,thevalueofUIDROPDOWNMENU_
MENU_VALUE is checked. This variable is set to the value attribute of the
menu header. These values can be anythingtables, functions, numbers, and
stringsas long as you can use them to distinguish between menus.
An optional second argument to the UIDropDownMenu_AddButton() function
indicates the level at which the new button should be added. Without this,
entering a submenu would only add buttons to the root menu instead of
popping out an additional level, and that would be confusing.
The resulting menu can be seen in Figures 23-4 and 23-5.
Figure 23-4: Example dropdown menu with Alpha expanded
Figure 23-5: Example dropdown menu with Beta expanded
Adding Functionality to Dropdowns
In addition to displaying text, dropdowns may contain more interactive
elements, such as checkboxes and color pickers. This section shows you how
to make dropdowns more interactive using these elements, and how to add
functionality to standard text buttons.
438 Part III Advanced Addon Techniques
Customizing Text Elements
Each text element in a dropdown menu can be customized using the following
attributes:
text (string)Text to be displayed on the menu item.
isTitleA boolean flag indicating if the button should be treated as a
title button (not clickable and gold text).
disabledA boolean flag indicating if the button is disabled.
colorCodeA string containing a color code to be applied to the text
in the format |cAARRGGBB, including alpha, red, green, and blue. This
attribute is valid only for buttons that are enabled.
notClickableA boolean flag indicating that the button should not be
clickable. This forces the button’s color to white, so you cannot color an
un-clickable item.
notCheckableA boolean flag indicating that the button cannot be
checked. This causes the button’s width to shrink because the check
button graphic is no longer necessary.
tooltipTitle (string)Title to be displayed in the tooltip that appears
when hovering the mouse over the menu option. Tooltips are only
displayed when Beginner Tooltips are enabled under Interface Options.
tooltiptext (string)Text to be displayed in the tooltip that appears
when hovering the mouse over the menu option. Tooltips are only
displayed when Beginner Tooltips are enabled under Interface Options.
textHeight (number)The height of the font used for the button text.
justifyHIf the button is not checkable and this attribute is set to CENTER,
the text on the button will be centered. No other text justification options
are available.
fontObjectA Font object to be used as a replacement for the normal
and highlight fonts in the dropdown.
You can replace your DropDownTest_Initialize() function with the follow-
ing to see each of these attributes in a working dropdown menu. Figure 23-6
shows the corresponding dropdown menu.
function DropDownTest_InitializeDropDown(self, level)
-- Create a table to use for button information
local info = UIDropDownMenu_CreateInfo()
info.text = “Title Button“
info.isTitle = true
UIDropDownMenu_AddButton(info)
info = UIDropDownMenu_CreateInfo()
Chapter 23 Creating Dropdown Menus 439
info.text = “Disabled Button“
info.disabled = true
UIDropDownMenu_AddButton(info)
info = UIDropDownMenu_CreateInfo()
info.text = “Colored Text“
info.colorCode = “|cFF33FF22“
UIDropDownMenu_AddButton(info)
info = UIDropDownMenu_CreateInfo()
info.text = “Not Clickable“
info.notClickable = true
UIDropDownMenu_AddButton(info)
info = UIDropDownMenu_CreateInfo()
info.text = “Not Checkable“
info.notCheckable = true
UIDropDownMenu_AddButton(info)
info = UIDropDownMenu_CreateInfo()
info.text = “Button with Tooltip“
info.tooltipTitle = “Tooltip title“
info.tooltipText = “Contents of the tooltip“
UIDropDownMenu_AddButton(info)
info = UIDropDownMenu_CreateInfo()
info.text = “Centered Text“
info.justifyH = “CENTER“
info.notCheckable = true
UIDropDownMenu_AddButton(info)
info = UIDropDownMenu_CreateInfo()
info.text = “Text with custom font“
info.fontObject = SystemFont_Small
UIDropDownMenu_AddButton(info)
end
Figure 23-6: Dropdown menu showing various buttons
440 Part III Advanced Addon Techniques
Function Menu Items
Any menu item can be set to call a function when it is clicked by using the
following set of attributes:
funcThe function to be called when the button is clicked.
arg1An argument to be passed to the function when it is called.
arg2Another argument to be passed to the function when it is called.
keepShownOnClickA boolean flag indicating whether or not the drop-
down menu should remain showing instead of disappearing when the
button is clicked.
Although the attributes are called arg1 and arg2, they are actually the
second and third arguments that are passed to the function. The first argument
is the button itself (which contains all of the valid attributes in the original
info table).
Add a function-enabled button to your dropdown using the following code:
info = UIDropDownMenu_CreateInfo()
info.text = “Function Button“
function info.func(button, arg1, arg2)
print(“CALL: Arg1: “ .. tostring(arg1) .. “ Arg2: “ .. tostring(arg2))
end
info.arg1 = “Foo“
info.arg2 = “Bar“
UIDropDownMenu_AddButton(info)
CheckButton Menu Items
Many dropdown menus are used for configuration, such as the ‘‘Player vs.
Player’’ setting that can be accessed by right-clicking the player frame. These
toggleable items make use of the checkbox included in each dropdown entry,
and the checked attribute to signify that the item is checked.
info = UIDropDownMenu_CreateInfo()
info.text = “Toggleable setting“
info.checked = SOME_SETTING
function info.func(button, arg1, arg2)
SOME_SETTING = not SOME_SETTING
print(“SOME_SETTING is “ .. tostring(SOME_SETTING)
end
UIDropDownMenu_AddButton(info)
This code defines a new button that can be clicked to change the value of
the global variable SOME_SETTING. Because it starts off with a value of nil,the
Chapter 23 Creating Dropdown Menus 441
button won’t be checked to start. Every time the button is clicked it will toggle
the setting and print a message to the chat frame. Figure 23-7 shows the button
when the SOME_SETTING is true.
Figure 23-7: Dropdown Test showing the ‘‘Toggleable setting’’ option
If you don’t want the menu to be hidden when someone clicks to toggle a
setting, you can use the keepShownOnClick attribute. The handler function will
still be called, and the checkbox will change without hiding the menu.
ColorPicker Menu Items
A dropdown menu can contain small color swatches that display a color, and
can be clicked to show a color picker frame. These allow for easy customization
of colors in a hierarchical dropdown menu. The color swatch can be customized
with the following attributes:
hasColorSwatchA boolean flag indicating if the menu item should
display a color swatch. This swatch can then be clicked to open the color
picker frame.
rThe red component of the color swatch (0255).
gThe green component of the color swatch (0255).
bThe blue component of the color swatch (0255).
swatchFuncA function called by the color picker when the color has
changed.
hasOpacity—A flag (1,nil) that adds the opacity slider to the color
picker frame.
442 Part III Advanced Addon Techniques
opacityThe percentage of opacity, as a value between 0.0 and 1.0,
indicating the transparency of the selected color.
opacityFuncA function called by the color picker when the opacity
changes.
cancelFuncA function called by the color picker when the user clicks
the Cancel button. This function is passed the previous values to which
the color picker is reverting.
The following example uses the color picker to change the color of the
player’s name on the player frame. The code accesses the font string PlayerName
to get the current color values, as well as to set the new color.
info = UIDropDownMenu_CreateInfo()
info.text = “Button Text Color“
info.hasColorSwatch = true
local oldr, oldg, oldb, olda = DropDownTest_ButtonText:GetTextColor()
info.r = oldr
info.g = oldg
info.b = oldb
function info.swatchFunc()
local r, g, b = ColorPickerFrame:GetColorRGB()
DropDownTest_ButtonText:SetTextColor(r, g, b)
end
function info.cancelFunc(prev)
DropDownTest_ButtonText:SetTextColor(prev.r, prev.g, prev.g)
end
UIDropDownMenu_AddButton(info)
When the dropdown is initialized, the function stores the current color of
the text string using DropDownTest_ButtonText:GetTextColor(), storing the
returns in the r,g,andbattributes of the new menu item. When the user
changes the color on the picker, the swatch function fetches the selected color
from the color picker frame and changes the color of the text.
When the cancel function is called, a table containing the previous color
is passed, so the cancel function uses it to restore the original color. This
definition creates the menu item shown in Figure 23-8. When the user clicks
the color swatch, the color picker frame (see Figure 23-9) opens. The color of
the text on the dropdown button is then changed to reflect the new choice.
Figure 23-8: Menu item to change the color of the button text
Chapter 23 Creating Dropdown Menus 443
Figure 23-9: The ColorPicker frame that appears when the color swatch is selected
Using Dropdowns for Selection
The examples earlier in this chapter used dropdowns to create popup menus.
Although these are used throughout the default user interface, dropdowns
can also be used to provide a selection box.
Three utility functions are provided to facilitate the graphical setup of the
frame:
UIDropDownMenu_SetWidth(frame, width, padding)
frameThe dropdown frame to adjust.
widthThe desired width of the frame.
paddingAn amount of padding on either side of the text; defaults
to 25.
UIDropDownMenu_SetButtonWidth(frame, width)
frameThe dropdown frame to adjust.
widthThe desired width of the button.
UIDropDownMenu_JustifyText(frame, justify)
frameThe dropdown frame to adjust.
justifyThe desired justification of the text, LEFT,RIGHT,CENTER.
Any dropdown that inherits from UIDropDownMenuTemplate is capable of
being used as a selection dropdown. Run the following Lua script in-game to
create a new sample menu:
if not DropDownMenuTest then
CreateFrame(“Frame“, “DropDownMenuTest“, UIParent,
444 Part III Advanced Addon Techniques
“UIDropDownMenuTemplate“)
end
DropDownMenuTest:ClearAllPoints()
DropDownMenuTest:SetPoint(“CENTER“, 0, 0)
DropDownMenuTest:Show()
local items = {
“Alpha“,
“Beta“,
“Gamma“,
“Delta“,
}
local function OnClick(self)
UIDropDownMenu_SetSelectedID(DropDownMenuTest, self:GetID())
end
local function initialize(self, level)
local info = UIDropDownMenu_CreateInfo()
for k, v in pairs(items) do
info = UIDropDownMenu_CreateInfo()
info.text = v
info.value = v
info.func = OnClick
UIDropDownMenu_AddButton(info, level)
end
end
UIDropDownMenu_Initialize(DropDownMenuTest, initialize)
UIDropDownMenu_SetWidth(DropDownMenuTest, 100);
UIDropDownMenu_SetButtonWidth(DropDownMenuTest, 124)
UIDropDownMenu_SetSelectedID(DropDownMenuTest, 1)
UIDropDownMenu_JustifyText(DropDownMenuTest, “LEFT“)
UIDropDownMenu_SetWidth is used to adjust the size of the text portion
of the dropdown menu, in this case to a value of 100. You should ensure
that the dropdown is wide enough to display any of the possible items.
UIDropDownMenu_SetButtonWidth allows you to set the width of the clickable
portion of the menu. Normally this is set to 24, which is the width of the actual
button graphic. Here it’s set to 124, making the entire selection box clickable.
UIDropDownMenu_JustifyText can be called to change the text jus-
tification (in this case, the text is left-justified). Finally, a call to
UIDropDownMenu_SetSelectedID selects an item from the list to be displayed
by its index in the list. Figure 23-10 shows the resulting selection menu.
Chapter 23 Creating Dropdown Menus 445
Figure 23-10: Selection dropdown menu
Menu items can be selected by name, by value, or by numeric index
using UIDropDownMenu_SetSelectedName,UIDropDownMenu_SetSelectedID,
and UIDropDownMenu_SetSelectedValue. You should use whichever method
makes the most sense for you.
Automating Menu Creation with EasyMenu
The process of creating dropdowns can be tedious, especially considering
that the table definitions can be verbose. Blizzard provides a system called
EasyMenu to ease the creation of menus, allowing you to define them in tables
ahead of time. This reduces the amount of code you need to write and localizes
all changes to the dropdown to a set of table definitions.
Create an addon skeleton called EasyMenuTest with the standard
EasyMenu.toc and EasyMenu.lua. This menu will be created in Lua, without
using XML. Add the following code to EasyMenu.lua:
if not EasyMenuTest then
CreateFrame(“Frame“, “EasyMenuTest“, UIParent, i
“UIDropDownMenuTemplate“)
end
if not EasyMenuButton then
CreateFrame(“Button“, “EasyMenuButton“, UIParent, i
“GameMenuButtonTemplate“)
end
menuTbl = {
{
text = “Alpha“,
hasArrow = true,
menuList = {
446 Part III Advanced Addon Techniques
{ text = “AlphaAlpha“, },
{ text = “AlphaBeta“, },
{ text = “AlphaGamma“, },
},
},
{
text = “Beta“,
hasArrow = true,
menuList = {
{ text = “BetaAlpha“, },
{ text = “BetaBeta“, },
{ text = “BetaGamma“, },
},
},
{
text = “Some Setting“,
checked = function()
return SOME_SETTING
end,
func = function()
SOME_SETTING = not SOME_SETTING
end,
},
}
EasyMenuButton:SetText(“EasyMenu Test“)
EasyMenuButton:SetPoint(“CENTER“, 0, 0)
EasyMenuButton:SetScript(“OnClick“, function(self, button)
EasyMenu(menuTbl, EasyMenuTest, “EasyMenuButton“, 0, 0, nil, 10)
end)
This example creates new button and dropdown frames and sets the button
to call the EasyMenu() function when it is clicked. Figure 23-11 shows the
resulting menu from the table definition. You may have noticed that the
checked attribute is set to a function here. This allows you to have dynamic
settings for checked items, because otherwise the true/false value would be
fixed when the table definition is created.
Figure 23-11: DropDown menu created using EasyMenu
Chapter 23 Creating Dropdown Menus 447
EasyMenu is extremely useful when you are creating a menu of mostly static
items, but falls short when working with more dynamic menus.
Creating Dynamic Menus
As you create more advanced addons, you may need to create a dropdown
menu based on returns from an API function. Occasionally you can create
the table ahead of time and use EasyMenu, but you can always use the more
verbose method introduced at the start of the chapter.
Type and run the following code snippet to create a dropdown that shows
the status of the ‘‘World Explorer’’ achievement; showing you which zones
you have explored and what areas you have not:
if not ExplorerDropDown then
CreateFrame(“Frame“, “ExplorerDropDown“, UIParent, i
“UIDropDownMenuTemplate“)
end
ExplorerDropDown:ClearAllPoints()
ExplorerDropDown:SetPoint(“TOPLEFT“, 50, -100)
ExplorerDropDown:Show()
local function initialize(self, level)
local info, achievementId
if UIDROPDOWNMENU_MENU_VALUE then
achievementId = UIDROPDOWNMENU_MENU_VALUE
else
achievementId = 46 -- Set the achievement to “World Explorer“
end
local id, name, points, completed = GetAchievementInfo(achievementId)
local numCriteria = GetAchievementNumCriteria(achievementId)
for i = 1, numCriteria do
local text, criType, completed, quantity, totalQuantity, name, i
flags, assetID, quantityString, criteriaID = i
GetAchievementCriteriaInfo(achievementId, i)
info = UIDropDownMenu_CreateInfo()
info.text = text
info.checked = completed
if (criType == CRITERIA_TYPE_ACHIEVEMENT) and assetID then
if GetAchievementNumCriteria(assetID) > 0 then
info.hasArrow = true
info.value = assetID
end
448 Part III Advanced Addon Techniques
end
UIDropDownMenu_AddButton(info, level)
end
end
UIDropDownMenu_Initialize(ExplorerDropDown, initialize)
UIDropDownMenu_SetWidth(ExplorerDropDown, 125)
UIDropDownMenu_SetButtonWidth(ExplorerDropDown, 124)
UIDropDownMenu_SetText(ExplorerDropDown, “World Explorer!“)
First you create the dropdown frame as in the previous examples, and
then query the achievements API to get the criteria for the ‘‘World Explorer’’
achievement (which happens to be achievement ID 46). Each criteria of the
selected achievement that is itself an achievement is tested to see if it too
contains subitems, and if so shows the arrow and sets the value attribute.
Figure 23-12 shows the dropdown menu in action.
Figure 23-12: World Explorer dropdown menu
Chapter 23 Creating Dropdown Menus 449
Summary
This chapter showed you how to create basic dropdown menus for your
own buttons as well as how to create selection dropdowns. You used a
manual method of initializing dropdowns, and used the EasyMenu system to
automatically create them.
The next chapter shows you how to construct and scan tooltips for infor-
mation.
CHAPTER
24
Scanning and Constructing
Tooltips
Tooltips are by far one of the most pervasive UI elements in World of Warcraft.
Whenever you move your mouse over a player, item, spell, talent, or almost
anything else in the game, you see a small tooltip in the bottom right of your
screen. This chapter introduces you to the inner workings of tooltips, showing
you how to create your own and how to get information that is available only
via tooltips.
Understanding the Tooltip System
Tooltips are used in World of Warcraft to display detailed information about
aspects of the game that might not be available through the game API. For
example, Figure 24-1 shows a spell tooltip that displays the name of the spell,
the resource cost for casting it, and the range along with the description
of the spell.
Tooltips are also used to provide contextual help when the mouse is over a
user interface element. For example, Figure 24-2 shows the tooltip displayed
when the mouse is over the player’s agility stat on the character frame, and
Figure 24-3 shows the tooltip displayed when the mouse is over the player
frame. This tooltip displays only if WoW’s ‘‘Beginner tooltips’’ option is
enabled. This option is enabled by default, but if you’ve turned it off you
might not see the tooltip.
All tooltips in the default user interface are created using the GameTooltip
frame type, which has methods to fill the tooltip with information about
different types of game objects (quests, items, spells, and so on).
451
452 Part III Advanced Addon Techniques
Figure 24-1: Spell tooltip for Obliterate
Figure 24-2: Agility tooltip on character frame
Figure 24-3: Tooltip for the player frame
Different Types of Tooltips
You may have encountered two different types of tooltips while playing the
game. To prevent confusion between the two, let’s call them contextual tooltips
and static tooltips. Most of the material in this chapter applies to either type of
tooltip, but you should be aware of the two types.
Contextual Tooltips
A contextual tooltip is used to give additional information about some
other item of interest, such as an interface element or something in the
three-dimensional game world. When the mouse moves over such an item
the tooltip is displayed, and is hidden when the mouse leaves that element.
In the default user interface, the most often used contextual tooltip is named
GameTooltip.
Chapter 24 Scanning and Constructing Tooltips 453
Static Tooltips
A static tooltip can be used to display information on its own, without
needing to be tied to a particular interface element. For example, any
links that are sent to you on the guild/party/trade channels are opened
in a static tooltip. This allows you to look at the information and move
it around your screen rather than having to leave your mouse in one
place. In the default user interface, the most often used static tooltip is
named ItemRefTooltip.
Tooltip Contents
As a frame, a tooltip consists of a series of lines of font strings, in two columns.
Figure 24-4 shows these columns and the names of the individual font strings.
As you can see, the first line is slightly larger than the others. This allows the
first line to be used as a title that stands out from the rest of the text.
Figure 24-4: GameTooltip with individual font string labels
When setting the contents of a tooltip, you normally won’t address these
font strings directly. Instead, you will make use of the GameTooltip API to
either load a predefined tooltip or add your own text.
Run the following code to set up and show the static tooltip ItemRefTooltip
on the screen. This allows you to use the various methods of setting/adding
text to the tooltip without needing to constantly set it up.
ItemRefTooltip:SetOwner(UIParent, “ANCHOR_PRESERVE“)
ItemRefTooltip:SetText(“Hello World!“)
ShowUIPanel(ItemRefTooltip)
This initial snippet shows the tooltip and displays the string Hello World!.
The tooltip can be moved around, but if you close it you will need to run the
snippet again to make the tooltip reappear.
Custom Text in a Tooltip
You have three different ways to manually add text to a tooltip. The SetText
method lets you set the text of the first line only, the AddLine method allows
you to add a line at a time (with an option to wrap strings that are too long),
and the AddDoubleLine method lets you add text to both the left and right
columns.
454 Part III Advanced Addon Techniques
SetText(‘‘text’’ [, r [, g [, b [, a]]]])
If your tooltip text consists of a single string that can be displayed in the
same size and color, you can use the :SetText() method to accomplish this. It
accepts five arguments:
textThe text to be displayed in the tooltip.
rThe red component of the text color (optional).
gThe green component of the text color (optional).
bThe blue component of the text color (optional).
aThe alpha value of the text (optional).
The text string can contain embedded color codes. For example, make sure
the static tooltip is still shown, and then run the following code:
ItemRefTooltip:SetText(“Tooltip Title\n“ ..
“|cffffffffThis is some text in a tooltip.\n“ ..
“It can contain multi-line strings.|r“)
Figure 24-5 shows the resulting tooltip. Note that all of the text is the same
size, and the second and third lines are a different color. The tooltip will
be sized wide enough to fit the contents, so you must be responsible for
any wrapping that is necessary.
Figure 24-5: Tooltip created using SetText
AddLine(‘‘text’’ [, r [, g [, b [, a [, wrap]]]]])
Rather than just destructively setting the text of a tooltip, the AddLine
method allows you to incrementally add lines. This function takes six
arguments:
textThe text to be displayed on the tooltip.
rThe red component of the text color (optional).
gThe green component of the text color (optional).
bThe blue component of the text color (optional).
aThe alpha value of the text (optional).
wrapTrue to wrap a long string of text onto multiple lines if necessary,
false or omitted otherwise.
Chapter 24 Scanning and Constructing Tooltips 455
Each call to this method adds another line to the tooltip. Run the following
to add a line to the already open tooltip:
ItemRefTooltip:AddLine(“This is a very long string that will be wrapped i
due to the fifth argument to this function“, 1, 1, 1, true)
ItemRefTooltip:Show()
Figure 24-6 shows the tooltip with the additional line added. You should be
able to see a slight size difference between the first line and the new line. In
addition, the tooltip remains roughly the same size, but the new text has been
wrapped to fit this width.
Figure 24-6: Result of adding a line to the previous tooltip
AddDoubleLine(‘‘text1’’, ‘‘text2’’ [, r1 [, g1 [, b1 [, r2 [, g2 [, b2]]]]]])
The AddDoubleLine function can be used to add text to both columns at once,
coloring them independently. The first argument is the left string and the
second argument is the right string. Run this code to add a two-column line to
the tooltip, shown in Figure 24-7:
ItemRefTooltip:AddDoubleLine(“Left“, “Right“, 0.2, 1, 0.2, 1, 0.2, 0.2)
ItemRefTooltip:Show()
Figure 24-7: Tooltip with a two-column line
Game Element Tooltips
The GameTooltip frame type provides several special methods that allow you
to load the tooltip with the information for some game element. Table 24-1
shows a list of these methods and the game elements for which they can load
tooltips. The usage for these methods vary and you should consult the API
documentation for whichever function is required.
456 Part III Advanced Addon Techniques
Table 24-1: GameTooltip Methods for Loading Information
METHOD NAME DESCRIPTION
SetAuctionItem Loads the tooltip for an item that is for sale in
the auction house.
SetAuctionSellItem Loads the tooltip for an item the player is
currently placing for sale in the auction house.
SetBackpackToken Loads the tooltip for a currency token being
displayed in the backpack frame.
SetBagItem Loads the tooltip for an item in a given bag/slot.
SetBuybackItem Loads the tooltip for an item available for
buyback at a merchant.
SetCurrencyToken Loads the tooltip for a currency token.
SetEquipmentSet Loads the tooltip for an equipment set,
specified by name.
SetExistingSocketGem Loads the tooltip for a gem already in the item
currently open for socketing.
SetGlyph Loads the tooltip for one of the player’s glyphs.
SetGuildBankItem Loads the tooltip for an item in the player’s
guild bank.
SetHyperlink Loads the tooltip for a spell, enchant, item, or
quest from a hyperlink.
SetHyperlinkCompareItem Loads the tooltip for the item currently
equipped in the slot used by an item
(represented by a hyperlink).
SetInboxItem Loads the tooltip with information about an
item attachment in the player’s mailbox.
SetInventoryItem Loads the tooltip with information about an
equipped item (on the player, or on a friendly
player unit within inspect distance).
SetLootItem Loads the tooltip with information about an
item in the loot window.
SetLootRollItem Loads the tooltip with information about an
item being rolled on by the player.
SetMerchantCostItem Loads the tooltip with information about a
non-monetary item cost for an item a merchant
is selling.
SetMerchantItem Loads information about an item available from
amerchant.
Chapter 24 Scanning and Constructing Tooltips 457
METHOD NAME DESCRIPTION
SetPetAction Loads the tooltip with information about an
action on the pet action bar.
SetPossession Loads the tooltip with information about the
type of possession the player is currently
engaged in.
SetQuestItem Loads the tooltip with information about an
item that is required to complete, or a reward
for a quest.
SetQuestLogItem Loads the tooltip with information about an
item that is required to complete, or a reward
for a quest in the player’s quest log.
SetQuestLogRewardSpell Loads the tooltip with information about the
spell that is a reward for the currently selected
quest in the quest log.
SetQuestLogSpecialItem Loads information about any special items that
must be used to complete the given quest in
the quest log.
SetQuestRewardSpell Loads the tooltip with information about the
spell reward for the currently viewed quest at
an NPC.
SetSendMailItem Loads the tooltip with information about an
item attached to the mail currently being sent.
SetShapeshift Loads the tooltip with information about one of
the player’s shapeshifts.
SetSocketGem Loads the tooltip with information about the
gem being placed into the item currently open
for socketing.
SetSocketItem Loads the tooltip with information about the
item currently open in the socketing UI.
SetSpell Loads the tooltip with information about a spell
in the player’s (or pet’s) spellbook.
SetTalent Loads the tooltip with information about a
talent.
SetTotem Loads the tooltip with information about one of
the player’s active totems.
SetTracking Loads the tooltip with information about the
currently selected tracking type.
Continued
458 Part III Advanced Addon Techniques
Table 24-1 (continued)
METHOD NAME DESCRIPTION
SetTradePlayerItem Loads the tooltip with information about an
item being traded by the player.
SetTradeSkillItem Loads the tooltip with information about a
tradeskill item, or required reagent for the item.
SetTradeTargetItem Loads the tooltip with information about an
item being traded by the target.
SetTrainerService Loads the tooltip with information about a
service available from a trainer.
SetUnit Loads the tooltip with information about a
given unit.
SetUnitAura Loads the tooltip with information about an
aura on a given unit.
SetUnitBuff Loads the tooltip with information about a buff
on a given unit.
SetUnitDebuff Loads the tooltip with information about a
debuff on a given unit.
Adding Information to the Tooltip
To see how to add information to a tooltip, you’ll write a very simple snippet
that adds information to item tooltips. The 3.1 patch to World of Warcraft
added an equipment manager system that allows you to organize weapons,
armor, and other equipment into sets that can be quickly equipped together.
Unfortunately, there is no tooltip indicator that shows if an item belongs to
any sets.
Loading the Tooltip with Item Information
When you move your mouse over items in your containers, the default
user interface uses the GameTooltip:SetBagItem() method to fill the
tooltip with the item’s information. Likewise, when moving the mouse
over the player’s inventory (the items you actually have equipped), the
GameTooltip:SetInventoryItem() method is called.
The timing of tooltips is a bit odd, since you might expect them to be
immediately loaded with the item information. What actually happens is that
the client may request the item information from the server, and when the
information is properly loaded and displayed, the OnTooltipSetItem widget
handler is called. An addon or script can use this handler to trigger any scans
of or additions to the information in the tooltip.
Chapter 24 Scanning and Constructing Tooltips 459
Run the following code in-game:
local numSets = GetNumEquipmentSets()
local inSet = {}
for i=1,numSets do
local name, icon, setID = GetEquipmentSetInfo(i)
local items = GetEquipmentSetItemIDs(name)
for slot,item in pairs(items) do
if inSet[item] then
inSet[item] = inSet[item] .. “, “ .. name
else
inSet[item] = name
end
end
end
local function OnTooltipSetItem(self)
local name, link = self:GetItem()
if name then
local equippable = IsEquippableItem(link)
local item = link:match(“Hitem:(%d+)“)
item = tonumber(item)
if not equippable then
-- Do nothing
elseif inSet[item] then
GameTooltip:AddLine(“Equipment Set: “ .. inSet[item], 0.2, 1, i
0.2)
else
GameTooltip:AddLine(“Item not in an equipment set“, 1, 0.2, i
0.2)
end
cleared = true
end
end
GameTooltip:HookScript(“OnTooltipSetItem“, OnTooltipSetItem)
The first section of code loops through all of the equipment sets and creates
a string for each item that lists the sets to which it belongs. The second section
sets an OnTooltipSetItem widget script that will be run anytime an item is
displayed in the tooltip. It checks to see which item is being shown, and then
adds a line indicating which equipment sets the item is in, if any.
ThelastlinehookstheOnTooltipSetItem script on the contextual tooltip
GameTooltip. As a result, the script will run anytime you move your
mouse over an item in-gameloot windows, trade windows, and the player
inspect window, for instance. It will not run when you click on an item
link in the chat window because that utilizes the ItemRefTooltip,which
hasn’t been hooked here.
460 Part III Advanced Addon Techniques
Getting Information from Tooltips
The client API has technical limitations that make some information available
only in the various game tooltips. For example, no API function currently exists
that can indicate whether an item is soulbound to the player characterthis
information can only be found in the item’s tooltip. This is one of the more
difficult things to do because you have to deal with localized values and can’t
always be sure of the order in which information will appear. For instance,
Figure 24-8 shows three different item tooltips.
Figure 24-8: Example item tooltips
You can see that the bound status of each tooltip appears in the second line
of text in the left-hand column if the item is bound in some way. The difficulty
is when working with items that aren’t bound because other information will
be in that place.
Accessing Individual Tooltip Lines
A tooltip is just a special sort of frame that contains a series of font strings.
There are two columns in the tooltip and as many lines as needed to display
the information. For the GameTooltip and ItemRefTooltip (and indeed, any
tooltip that inherits from GameTooltipTemplate) frames, these font strings are
regularly named:
GameTooltipTextLeft1
GameTooltipTextLeft2
GameTooltipTextRight1
GameTooltipTextRight2
You can get the contents of the second tooltip line in the left column by
calling GameTooltipTextLeft2:GetText().
Chapter 24 Scanning and Constructing Tooltips 461
Checking Soulbound Status
Here you write a simple snippet of code that changes the border color
of the tooltips when an item is soulbound. To accomplish this, use the
OnTooltipSetItem script to detect items being loaded. Then access the indi-
vidual tooltip lines to see if the item is soulbound, and change the border color.
Run the following code:
GameTooltip:SetScript(“OnTooltipSetItem“, function(self)
local boundText = GameTooltipTextLeft2:GetText()
if boundText == ITEM_SOULBOUND or
boundText == ITEM_ACCOUNTBOUND then
self:SetBackdropBorderColor(0, 0, 0)
end
end)
Using Global Strings for Localization
You might be tempted to use the strings Soulbound and Account Bound,but
then your addon will work only on English clients. Instead, this code uses the
globally defined strings ITEM_SOULBOUND and ITEM_ACCOUNTBOUND. The strings
aredenedinFrameXML/GlobalStrings.lua as follows:
ITEM_SOULBOUND = “Soulbound“;
ITEM_ACCOUNTBOUND = “Account Bound“;
These localized strings are loaded by the default user interface, and differ
depending on which locale the client is using. By comparing the tooltip against
the global values, you can ensure the code works properly regardless of what
language the user interface is displayed in.
The best place to look for the global strings for some part of the user interface
is the GlobalStrings.lua file; search by the contents of the string used in your
version of the client.
Replacing a Script Instead of Hooking a Script
In this example, the code uses the SetScript method to set the widget script
handler on the frame directly, rather than using the HookScript method. Each
frame can have only one handler for each widget script, so this will overwrite
any script that is already set. It’s generally better to use HookScript() for an
addon released to to the public because SetScript() may destroy handlers
placed by other addons, leading to runtime errors.
You could alter the snippet to use HookScript(), but if you want to tweak
it and run it multiple times, you’ll notice that every version of your script that
you run is called every time the tooltip is loaded. If these versions conflict
462 Part III Advanced Addon Techniques
with each other, they might give you very confusing results. In development,
using SetScript() is fine, but more often than not you will want to use
HookScript().
Summary
In this chapter you learned how tooltips are constructed and how to add
your own information to them. In addition, you were introduced to a simple
technique for scanning information from a game tooltip. In the next chapter,
you learn how to use the secure snippets functionality of secure templates to
take protected action in combat.
CHAPTER
25
Taking Protected Action
in Combat
In Chapter 15, you learned how the secure template system protects WoW
game play from being automated through the user interface, by preventing
protected frames from being moved, shown or hidden, created, or having
their behavior changed during combat. However, several legitimate occasions
exist when it might be desirable for these things to happen during combat; for
instance, if someone’s target dies or is deselected during combat, the target
frame should be hidden, and shown again when the player picks a new target.
The stock target frame can rely on the fact that Blizzard wrote it and its code
is secure, but an addon that wants to provide a similar feature needs to use
a different mechanism.
Just before the Wrath of the Lich King expansion was released, a new system
was introduced to allow addons to load code of their own for secure execution,
and for Blizzard to strictly control what information and actions are available
to code that is being run securely. These chunks of controlled, authorized code
are referred to as snippets.
Snippets: The Basis of Secure Action
Of course, the whole system of protected game actions is founded on the
principle that addon code is ‘‘tainted,’’ and that secure code becomes tainted as
soon as addon code tries to interfere with it. Snippets solve part of this problem.
How Can Addon Code Be Secure?
A snippet is a string containing Lua source code, typically stored in a frame
attribute. Because it is stored in a frame attribute, secure code can retrieve it
463
464 Part III Advanced Addon Techniques
without becoming tainted; and because that code can remain secure, it can
compile the attribute contents into an executable function that is also secure.
When it compiles this function, it can also restrict its access to specific functions
and variables so that the secure function can’t use information that the Blizzard
designers don’t want influencing sensitive decisions.
Writing a Snippet
A snippet is the body of a function, without the function (args, ...) and
final end tags. These elements are provided by the secure code that compiles
the snippet into a usable function. Because many snippets emulate frame script
handlers (OnClick,OnShow, and so on), the argument list is generally the same
as it would be in the equivalent XML script <OnClick>,<OnShow>, and so forth.
Snippets often contain code comprised of quotes, line breaks, and other
characters that normally need to be escaped inside Lua string literals. Because
of this, there is an emerging convention to enclose snippet literals in [[long
brackets,]] which ignore all special characters (except the end of the bracket).
This has the advantage of allowing you to format your code in a more natural
fashion, as well as often making it easier for you to distinguish the secure and
insecure parts of your addon code.
You can demo a very simple snippet with the following line:
/run SecureHandlerExecute(PlayerFrame, [[self:Hide()]])
By itself, this isn’t terribly exciting. Insecure code can’t use SecureHandler
Execute during combat, and that code could always hide the player frame
directly. SecureHandlerExecute is mostly used to perform setup on more com-
plex secure handler frames. The real power of snippets and secure execution
comes from the ability to attach snippets to frames that will run them securely
in response to user input or selected state changes. Before we move on to that,
though, put the player frame back by running the following code (snippets
can be stored in variables as well as in string literals):
local showAction = [[self:Show()]]; i
SecureHandlerExecute(PlayerFrame, showAction)
Secure Handler Frames
To get WoW to compile and run your snippets, you have to store and attach
them correctly. The most common mechanism for this is a set of protected
templates called the secure handlers.
Much the same way as SecureActionButtonTemplate provides a secure
function as its OnClick handler, these templates each provide one or two
secure functions as various script handlers. Each of these functions looks for
Chapter 25 Taking Protected Action in Combat 465
a snippet in a fixed relevant attribute and executes it when its corresponding
handler is triggered; for example, when someone clicks a button inheriting
from SecureHandlerClickTemplate, that button’s OnClick function looks for
a snippet in its _onclick frame attribute and tries to execute it. It also passes a
reference to the button clicked and copies of the button and down arguments
to the script as arguments to the snippet.
Secure handler templates are available for most scripts that represent a user
interaction (OnClick,OnDoubleClick,OnMouseUp/OnMouseDown,OnMouseWheel,
OnEnter/OnLeave,andOnDragStart/OnReceiveDrag), as well as scripts for
responding to certain actions that can only be triggered by protected code
(OnShow/OnHide and OnAttributeChanged), which are discussed in more detail
later in the chapter.
As an example, you can create an addon that modifies the stock UI’s extra
action bars (the ones that can be turned on around the bottom and right edges
of the UI), so that each one only appears when you’re mousing over it. Because
the frames you have to create will have no visual elements of their own, and
you are primarily trying to interact with existing UI elements, this is easier to
do from Lua. Run the following code in-game:
local mousein = [[
self:GetFrameRef(“subject“):Show()
]]
local mouseout = [[
self:GetFrameRef(“subject“):Hide()
]]
for i, bar in ipairs{MultiBarRight, MultiBarLeft, i
MultiBarBottomRight, MultiBarBottomLeft} do
local watcher = CreateFrame(“Frame“, “ShyBarsWatcher“..i, i
bar:GetParent(), “SecureHandlerEnterLeaveTemplate“)
watcher:SetFrameLevel(bar:GetFrameLevel() - 1)
watcher:SetAllPoints(bar)
bar:SetParent(watcher)
bar:Hide()
watcher:SetAttribute(“_onenter“, mousein)
watcher:SetAttribute(“_onleave“, mouseout)
SecureHandlerSetFrameRef(watcher, “subject“, bar)
end
This code loops over each of the supplemental action bars, and attaches a
frame to each bar that will ‘‘watch’’ for mouseover events. The only really new
part here is the use of the SecureHandlerEnterLeaveTemplate to create the
new frames. This is the template that triggers certain snippets when someone
mouses in or out of it. The rest of the code uses the SetAllPoints() method to
make sure that the frame is watching the same area that the bar takes up when
it’s present and makes sure that the watcher frame will not cover its bar when
shown (this could make the action bar difficult to click).
466 Part III Advanced Addon Techniques
This isn’t a perfect example of making the action bars hide (for instance, if
your mouse leaves the area while being over one of the extra action bars, they
might not hide), but it’s a good first approximation that shows the basics of
the snippets system.
WARNING The game stores a character’s preferred setting for which action
bars should be shown on the server, and they aren’t available to the client until
the VARIABLES_LOADED event has fired. If you were loading this into an addon,
you would want to delay hiding the bars until then, because the stock UI would
reshow them.
Now, let’s break down the two chunks of code that are less familiar. The
mousein and mouseout local variables at the beginning of the file are chunks
of code in string form; that is, snippets. SetAttribute() calls attach these
snippets to the attributes that the template’s OnEnter and OnLeave handlers
will invoke. The other issue is that to make sure that secure snippets can’t
use disallowed information, they are run with a limited version of the global
environment that only includes certain functions, and frames don’t normally
exist there. So, to make the action bar frame that will be shown and hidden
available to the snippets, you have to store it in something called a frame
reference; this is basically a sanitized version of the frame (called a frame
handle, discussed more later), stored in the first frame’s frameref-subject
attribute (or whatever name you supplied when you set the frame reference).
Because the _onenter and _onleave scripts will be called with watcher as
self, the frame can then be retrieved with self:GetFrameRef(“subject“).
Handler Template Reference
The simpler, and more common, secure templates respond directly to vari-
ous sorts of user interaction; these are generally triggered with the mouse, but
some can also be triggered from key binding actions by using SetBindingClick.
Table 25-1 shows a list of the valid templates. Each template in the first column
supplies a handler for the frame script that calls the snippet named in the second
column, providing the arguments listed in the third column. For these tem-
plates, the arguments provided to the snippet are in the same order, and have
the same names, as would be supplied to the equivalent script element contents
in an XML frame definition; that is, an _onclick snippet receives the same set
of implicit arguments as the code in an <OnClick>...</OnClick> element.
The last ‘‘interaction’’ template is slightly more complicated. Dragging a
frame through the StartMoving() method call is not a protected operation
(because it is inherently interactive), so SecureHandlerDragTemplate is pri-
marily intended for buttons that you can drag things in or out of, such as
customizable action buttons. The button argument is the button that was
Chapter 25 Taking Protected Action in Combat 467
held down to initiate the drag action, but the other arguments are the same
information returned by GetCursorInfo()the kind of action or resource
held on the cursor, the identifier or value of the cursor’s contents (such as the
amount of money or the ID of the spell or item), and possible supplemental
information (such as whether a spell is a “BOOK“ spell or a “PET“ spell) passed
in vararg argument(s).
Table 25-1: Secure Handler Templates and Their Snippets
TEMPLATE SNIPPETS ARGUMENTS
SecureHandler
ClickTemplate
_onclick self,button,down
SecureHandler
DoubleClickTemplate
_ondoubleclick self,button,down
SecureHandler
MouseUpDownTemplate
_onmouseup self,button
_onmousedown self,button
SecureHandler
MouseWheelTemplate
_onmousewheel self,delta
SecureHandler
EnterLeaveTemplate
_onenter self
_onleave self
SecureHandler
DragTemplate
_ondragstart self,button,kind,value,
...
_onreceivedrag self,button,kind,value,
...
SecureHandler
ShowHideTemplate
_onshow self
_onhide self
SecureHandler
AttributeTemplate
_onattribute
changed
self,name,value
SecureHandler
StateTemplate
_onstate-* self,stateid,newstate
Moreover, the _ondragstart and _onreceivedrag snippets may use a return
statement to have the game load the cursor with something new or exchange
its current contents. For instance, if you want to write a button that uses
the action slots to store its content much like the stock buttons do, you
can have the button inherit from both SecureActionButtonTemplate and
468 Part III Advanced Addon Techniques
SecureHandlerDragTemplate, and use the following snippet in the button’s
_ondragstart and _onreceivedrag attributes:
local pickupAction = [[return “action“, self:GetAttribute(“action“)]]
button:SetAttribute(“_ondragstart“, pickupAction)
button:SetAttribute(“_onreceivedrag“, pickupAction)
Your drag handlers can return any of the following sequences:
return “action“, actionSlot
return “bag“, equippedBag
return “bagslot“, bagID, slotNumber
return “inventory“, inventorySlot
return “item“, name or itemID
return “macro“, name or macroIndex
return “petaction“, petSlot
return “spell“, index, “BOOK“ or “PET“
return “spell“, name or spellID
return “companion“, “MOUNT“ or “CRITTER“, index
return “equipmentset“, name
return “money“, amount
return “merchant“, slot
You can also add “clear“ to the beginning of any of these lists to clear the
cursor first, such as to pick up the contents of an action slot without dropping
anything into it that was already on the cursor. For instance, you might change
the drag-start handler to
button:SetAttribute(“_ondragstart“, [[return “clear“, “action“, i
self:GetAttribute(“action“)]])
The last group of templates are intended to react to changes in frame
visibility or attribute values. These changes can be triggered by other snippets
acting on frames securely, or by state drivers that you have registered for the
frame(discussedinmoredetaillaterinthechapter).
Integrating a Click Handler with a Secure Action Button
One other facility offered by SecureActionButtonTemplate is the ability to
run click snippets for undefined “type“ attributes. If, for instance, button:
GetAttribute(“type“) == “menu“ and button:GetAttribute(“_menu“) con-
tains a snippet, the secure action button will run it as a click handler, with
self,button,anddown arguments. This means that you can intermingle
secure actions with other secure behaviors on a single button by using modi-
fier and mouse button selection. For instance, you can easily create menus for
Chapter 25 Taking Protected Action in Combat 469
expanded click-casting, as in the following example addon for paladin char-
acters, BlessedMenus. Start by creating a BlessedMenus folder in your AddOns
directory, then create the file BlessedMenus.toc and enter the following:
## Interface: 30300
## Title: BlessedMenus
## Notes: Creates menus on party frames to select spells to cast on them
BlessedMenus.xml
BlessedMenus.lua
Next, create the file BlessedMenus.xml in the same directory, and start by
entering the following:
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd>
<Button name=“BlessedMenusSpellButtonTemplate“ enableMouse=“true“ i
inherits=“SecureActionButtonTemplate“ virtual=“true“>
<Size x=“144“ y=“16“ />
<Layers>
<Layer level=“ARTWORK“>
<Texture parentKey=“icon“>
<Size x=“16“ y=“16“ />
<Anchors>
<Anchor point=“TOPLEFT“ />
</Anchors>
</Texture>
</Layer>
</Layers>
<ButtonText inherits=“GameFontHighlight“ justifyH=“LEFT“ />
<HighlightTexture alphaMode=“ADD“>
<Color r=“0.75“ g=“0.75“ b=“0.6“ a=“0.5“ />
</HighlightTexture>
</Button>
</Ui>
This is the beginning of a template that you can use for popup menu entries.
So far, it’s basically a horizontal bar containing a text string, with a small
icon at the left side. It has a plain yellow highlight texture to indicate which
menu item is currently being pointed at. Add the basic action button attributes
between the </Layers> and <ButtonText> tags:
<Attributes>
<Attribute name=“type“ value=“spell“ />
<Attribute name=“useparent-unit“ value=“true“ type=“boolean“ />
</Attributes>
470 Part III Advanced Addon Techniques
These define the consistent parts of the button behavior. All these menu
items will be spell buttons, and they will cast on the unit whose frame was
clicked to bring up the spell menu. Note that you use the type tag attribute
heretosettheframeattributetoavaluewiththeLuatype“boolean“.
Add a Scripts section immediately after the Attributes block and before
the <ButtonText> tag:
<Scripts>
<OnLoad>
self:GetFontString():SetPoint(“LEFT“, self.icon, “RIGHT“, 2, 1)
self:RegisterEvent(“PLAYER_ENTERING_WORLD“)
</OnLoad>
</Scripts>
The first line ensures that the button’s text is placed correctly in the button
(because the icon texture is created using a key rather than a name, you can’t
currently refer to it from an XML <Anchor> tag’s relativeTo attribute). The last
line prepares the button to deal with the fact that its spell icon isn’t available
when your addon first loads, which is fully addressed in the next handler (add
it right before the </Scripts> tag):
<OnEvent>
self.icon:SetTexture(GetSpellTexture(self:GetAttribute(“spell“)))
</OnEvent>
This handler is run in response to the PLAYER_ENTERING_WORLD event, when
the client has fully loaded spell icons. These icons are actually loaded by the
earlier SPELLS_CHANGED event, but that event does not fire when you reload the
UI, so the more reliable PLAYER_ENTERING_WORLD is used. Also, if you watch
event traces, you will see that the SPELL_CHANGED event fires quite a number
of times during logging in. Waiting until the PLAYER_ENTERING_WORLD event
helps you avoid all of these.
Paladins use three major groups of beneficial spells, so you’ll create three
menus, one for each. To facilitate that, create a menu template in the same file,
right before the </Ui> tag:
<Frame name=“BlessedMenusMenuTemplate“ hidden=“true“ i
protected=“true“ virtual=“true“>
<Size x=“160“ y=“18“ />
<Backdrop bgFile=“Interface\Tooltips\UI-Tooltip-Background“ i
edgeFile=“Interface\Tooltips\UI-Tooltip-Border“ tile=“true“>
<EdgeSize val=“16“/>
<TileSize val=“16“/>
<BackgroundInsets left=“4“ right=“4“ top=“4“ bottom=“4“/>
<BorderColor r=“1“ g=“1“ b=“1“ />
<Color r=“0.09“ g=“0.09“ b=“0.19“ a=“1.0“ />
</Backdrop>
Chapter 25 Taking Protected Action in Combat 471
<Attributes>
<Attribute name=“useparent-unit“ value=“true“ type=“boolean“ />
</Attributes>
</Frame>
This creates a simple tooltip-type frame. Like the child buttons, the
useparent-unit attribute is set so that unit requests on the buttons can pass
all the way up to whatever unit button currently owns the menu. Now that the
templates are ready, you can save and close the XML file; the rest of the heavy
lifting is done dynamically at load time, so create the file BlessedMenus.lua in
the BlessedMenus directory, if needed, and start it by entering the following:
local function BlessedMenu(name, ...)
local self = CreateFrame(“Frame“, name, nil, i
“BlessedMenusMenuTemplate“)
self.buttons = {}
for i=1, select(’#’, ...) do
local spellName = select(i, ...)
local button = CreateFrame(“Button“, nil, self, i
“BlessedMenusSpellButtonTemplate“)
self.buttons[i] = button
button:SetAttribute(“spell“, spellName)
button:SetText(spellName)
if i == 1 then
button:SetPoint(“TOPLEFT“, 8, -8)
else
button:SetPoint(“TOPLEFT“, self.buttons[i - 1], i
“BOTTOMLEFT“, 0, -2)
end
end
self:SetHeight(#self.buttons * 18 + 14)
return self
end
This function does all the work of creating a menu frame, as well as creating
and placing the choice buttons in the menu, which it does by name. Add the
following code to create three menus using this function:
local heals = BlessedMenu(“BlessedMenusHeals“,
“Holy Light“,
“Flash of Light“,
“Lay on Hands“
)
local hands = BlessedMenu(“BlessedMenusHands“,
“Hand of Protection“,
“Hand of Freedom“,
“Hand of Salvation“,
“Hand of Sacrifice“
)
472 Part III Advanced Addon Techniques
local blessings = BlessedMenu(“BlessedMenusBlessings“,
“Blessing of Might“,
“Blessing of Kings“,
“Blessing of Wisdom“
)
Now that you’ve defined the menus, it’s time to start preparing the code
that will drive the secure behaviors. Add the following:
local openSpellList = [[
local menu = IsAltKeyDown() and “blessings“
or IsControlKeyDown() and “heals“
or IsShiftKeyDown() and “hands“
menu = menu and self:GetFrameRef(menu)
if menu and menu:IsShown() and menu:GetParent() == self then
menu:Hide()
return
end
if menu then
menu:Hide()
menu:SetParent(self)
menu:SetPoint(“TOPLEFT“, “$cursor“)
menu:SetFrameLevel(self:GetFrameLevel() + 2)
menu:Show()
end
]]
This is the snippet code that the party and player buttons will run when
clicked with certain modifiers, which you add in a moment. It uses information
about the current modifiers to determine which frame reference to retrieve
and open. If that menu is already open on the unit frame in question, it hides
it and takes no further action; if the menu is not open (hidden), or is open on
another unit frame, it is re-parented to the frame that was clicked, making sure
it appears above the frame clicked, and opened. It is also moved to appear
by the point clicked, using an arguments to SetPoint(),$cursor,thatplaces
the point anchored by the mouse’s current location (it will not automatically
follow the mouse). But of course, the code will never run unless it is attached
to some frames; add the load-time code to do so just after the snippet:
for i, frame in ipairs{PlayerFrame, PartyMemberFrame1, i
PartyMemberFrame2, PartyMemberFrame3, PartyMemberFrame4} do
frame:SetAttribute(“shift-type1“, “spelllist“)
frame:SetAttribute(“ctrl-type1“, “spelllist“)
frame:SetAttribute(“alt-type1“, “spelllist“)
frame:SetAttribute(“_spelllist“, openSpellList)
SecureHandlerSetFrameRef(frame, “blessings“, BlessedMenusBlessings)
SecureHandlerSetFrameRef(frame, “heals“, BlessedMenusHeals)
SecureHandlerSetFrameRef(frame, “hands“, BlessedMenusHands)
end
Chapter 25 Taking Protected Action in Combat 473
This code starts by iterating over the player frame and the frames for all
party members and making the same changes to each one:
First, it sets “spelllist“ as the type for modified left-clicks. This type is
not defined by the secure action button template, so it will look for a function
in self.menu or a snippet in self:GetAttribute(“_spelllist“). You should
use the latter because setting a key on the frame would introduce taint. As
you did with the ShyBars example given before (the one that auto-hides the
extra action bars), you use SecureHandlerSetFrameRef to import references to
the actual frames into the environment for the snippet to access when it runs.
Figure 25-1 shows the BlessedMenus addon.
Figure 25-1: BlessedMenus in action
A couple issues still exist with BlessedMenus; if you show one menu while
another one is open (such as by Shift+clicking, then Alt+clicking), they will
overlap, instead of closing the first one. Also, the menu does not disappear
when you choose an option from it. You learn how to address both these issues
in the following sections.
Preserving State and Controlling Information
The secure frame management system in versions 2.02.4 of WoW used a
single variable per header, called state, to summarize all the factors it used to
control frames. It was possible to use multiple control factors, but if you had an
474 Part III Advanced Addon Techniques
addon like the original version of Goose that could show or hide frames based
on three different factors (whether or not you were in stealth, in combat, or
mounted), it needed eight different states (two possibilities for combat times
two for stealth times two for mount equals eight) and it had to be able to
handle all the possible combinations of which state to go to when any one of
these factors changed.
Two things make the existing system generally easier to manage. First,
snippets are capable of examining the game state, attributes on relevant
frames, and similar factors, directly when triggered to determine the state they
should set up. Second, the snippets associated with a frame can store as many
distinct pieces of information as they need to keep track of, in private globals.
Private Global Environments
Each function has an environment, which is a table where it stores and seeks
any global variable references made in its body. Because each new function
is created with the same environment as the function that created it, all the
functions created in the stock UI or addon files normally share the same
environment unless they specify otherwise at some point.
The functions created when the secure handler infrastructure compiles
snippets use their own environments, which is part of how their access to
game information that’s not supposed to be used for secure actions is strictly
controlled (such as how low on health your target is, for example). Because
functions are also normally found by calling global variables, functions that
retrieve prohibited information simply aren’t available from inside a secure
environment. But snippets running in that environment can also store their
own globals there, which persist from one call to another. Moreover, all the
snippets associated with a frame typically share an environment, allowing
them to share input into their frame’s state.
As a simple example of how this can be used, you can fix one of the issues
with BlessedMenus, namely, that when you open one menu on a frame and
then another, the first one stays open behind the second one.
Open BlessedMenus.lua and look for your definition of the openSpellList
snippet. Alter it to look like this (changed lines are highlighted):
local openSpellList = [[
local menu = IsAltKeyDown() and “blessings“
or IsControlKeyDown() and “heals“
or IsShiftKeyDown() and “hands“
menu = menu and self:GetFrameRef(menu)
if lastMenu and lastMenu:IsShown() and i
lastMenu:GetParent() == self then
lastMenu:Hide()
if lastMenu == menu then
Chapter 25 Taking Protected Action in Combat 475
return
end
end
if menu then
menu:Hide()
menu:SetParent(self)
menu:SetPoint(“TOPLEFT“, “$cursor“)
menu:SetFrameLevel(self:GetFrameLevel() + 2)
menu:Show()
lastMenu = menu
end
]]
Every time you open a menu, you store it in the lastMenu variable. Then
when you go to later open another menu, you can hide whatever was shown
last. lastMenu is neither a local variable nor an argument to the function, so Lua
will treat it as a global. However, you won’t see any changes to it outside the
snippet by looking in _G.lastMenuOpened; it’s a private global in the frame’s
own personal environment. You can use it as a way to track which menu you
last opened so that you can close it as needed before opening another one.
Secure API Functions
Private globals are usually used as a way for snippets to store internal state
information, but because functions in Lua are actually variables that contain
references to those functions, the private environment is also how snippets are
restricted to secure portions of the API. The following standard Lua functions
work similarly inside a snippet to the way they do in the normal World of
Warcraft Lua environment: type,select,tonumber,tostring,print,pairs,
ipairs,next,unpack,andthetable,string,andmath libraries, as well as their
deprecated global forms such as tremove.
The following WoW API functions are available to snippets in basically the
same form as they work in normal code:
SecureCmdOptionParse GetMouseButtonClicked
GetShapeshiftForm GetActionBarPage
IsStealthed, UnitExists GetBonusBarOffset
UnitIsDead, UnitIsGhost IsMounted, IsSwimming
UnitPlayerOrPetInParty IsFlying
UnitPlayerOrPetInRaid IsFlyableArea
IsRightAltKeyDown IsIndoors
IsLeftAltKeyDown IsOutdoors
IsAltKeyDown GetBindingKey
IsRightControlKeyDown HasAction
IsLeftControlKeyDown IsHarmfulSpell
IsControlKeyDown IsHarmfulItem
476 Part III Advanced Addon Techniques
IsLeftShiftKeyDown IsHelpfulSpell
IsRightShiftKeyDown IsHelpfulItem
IsShiftKeyDown RegisterStateDriver
IsModifierKeyDown GetActionInfo
IsModifiedClick
The following player information functions behave basically the same as the
equivalent unit information functions, but only allow you to inquire about the
player:
PlayerCanAttack PlayerIsChanneling
PlayerCanAssist PlayerInCombat
UnitHasVehicleUI is available inside the secure environment, but only
returns useful information for units that are friendly to the player: true for
friendly units that have a vehicle interface, false for friendly units that don’t,
and nil for all non-friendly units.
Two new player information functions are also available to snippets: Player
InGroup returns “raid“ if the player is in a raid group, “party“ if the player is
in a party but not a raid group, and nil if the player is not in any group; Player
PetSummary returns the name and creature family of the player’s pet, if any.
The table module inside the secure environment includes one function
that is not part of the normal table module. For security reasons, the snippet
execution engine will not compile snippets that create tables directly using the
table constructor {}. Instead, you can create tables for your snippets to store
information using table.new(...). If arguments are supplied, they are added
to the new table under consecutive integer keys, starting from 1. There is no
way to initialize a table with non-integer keys using table.new(),butyoucan
set them afterward using conventional table syntax.
The other action the secure environment has to prohibit to snippets is the
creation of functions, but repetitive tasks can be executed in a similar way
using the control object provided in each frame’s environment.
The control Object
The secure environment provides something called a control object to serve
two principal functions: The first is to be able to trigger insecure functions
that have full access to presentational elements such as textures (but without
secure privileges to affect protected execution), and the second is to isolate
small chunks of repetitive code in snippets, so that they can be called like
functions.
When you have to make cosmetic updates to a frame based on changes to its
attributes or other triggers, you can assign a function to a key on that frame in
advance. Then, when secure code running in that frame’s environment wants
to trigger that function, it can call control:CallMethod(keyName, ...).This
will find originalFrame as the frame owning the secure environment, retrieve
Chapter 25 Taking Protected Action in Combat 477
originalFrame[keyName], and if it is a function, call it with (originalFrame,
....) as arguments. The call will be made insecurely, so the function will run
without any special privileges, but with full access to the global environment.
When the function returns, the snippet that called it remains secure, but any
returns from the method function called are discarded and not available to the
secure environment.
The control object can also run snippets, whether provided as string literals
or stored in variables. The control:Run(snippet, ...) function will run the
specified snippet with the owning frame as self and the remaining arguments
passed as the vararg expression. The control:RunFor(frameHandle, snippet,
...) function will run the supplied snippet with frameHandle as self,with
the rest of the arguments passed in the vararg expression, but still in the
environment of the frame calling control:RunFor.
The control:RunAttribute(name, ...) function is very similar to
control:Run, but instead of taking snippet code directly, it retrieves the
snippet to run from owningFrame:GetAttribute(name). This is presently
about the only way to securely interact with any attribute on a frame that
starts with an underscore.
The final method of the control object is largely obsolete, but can occasion-
ally used as a timesaver. control:ChildUpdate(snippetID, message) checks
each child of the calling frame for a “_childupdate-“..snippetID attribute
or a “_childupdate“ attribute in that order. It then calls that snippet on that
child, with the child itself, snippetID,andmessage as arguments, in the child
frame’s environment.
Frame Handles
Because true tables can’t exist in WoW’s secure sandboxes (the objects manip-
ulated by the table library are actually special proxy objects), frames can’t be
imported directly into snippet code. To allowsecurecodetomanipulateframes,
proxy objects called frame handles are created. The self argument received by
most snippets is actually a frame handle, and SecureHandlerSetFrameRef
stores a frame handle in an attribute on the target frame where it can be
retrieved.
For the most part, frame handles act like frames. They have many of the
same methods, but a few important distinctions exist:
Frame handles are actually userdata objects, so you cannot set values
on their keys as you can with frames.
Most frame handle methods throw an error if used during combat for
a frame handle that represents an unprotected frame.
Frame handles also have some changed methods, as well as a few
methods that don’t normally exist on real frames.
478 Part III Advanced Addon Techniques
To get a taste for using frame handles, press Esc to enable your right action
bar, navigate to Interface Options, select ActionBars, and check the Right Bar
checkbox. Then run the following script in-game:
local function ConstructButton(name, parent, baseTexture)
local self = CreateFrame(“Button“, parent:GetName()..name, parent, i
“SecureHandlerClickTemplate“)
parent[name:lower()] = self
self:SetHeight(32)
self:SetWidth(32)
self:SetNormalTexture(baseTexture..“-Up“)
self:SetPushedTexture(baseTexture..“-Down“)
self:SetHighlightTexture(baseTexture..“-Highlight“, “ADD“)
return self
end
local advance = MultiBarRight.advance or ConstructButton(“Advance“, i
MultiBarRight, [[Interface\MainMenuBar\UI-MainMenu-ScrollUpButton]])
advance:SetPoint(“BOTTOM“, MultiBarRight, “TOP“)
advance:SetAttribute(“_onclick“, [[
bar = bar or self:GetParent()
local page = tonumber(bar:GetAttribute(’actionpage’)) or 4
if page <= 1 then
page = 7
end
bar:SetAttribute(“actionpage“, page - 1)
buttons = buttons or table.new(bar:GetChildren())
for i, button in ipairs(buttons) do
button:SetAttribute(“touch“)
end ]]
)
local regress = MultiBarRight.regress or ConstructButton(“Advance“, i
MultiBarRight, [[Interface\MainMenuBar\UI-MainMenu-ScrollDownButton]])
regress:SetPoint(“TOP“, MultiBarRight, “BOTTOM“)
regress:SetAttribute(“_onclick“, [[
bar = bar or self:GetParent()
local page = tonumber(bar:GetAttribute(’actionpage’)) or 2
if page >= 6 then
page = 0
end
bar:SetAttribute(“actionpage“, page + 1)
buttons = buttons or table.new(bar:GetChildren())
for i, button in ipairs(buttons) do
button:SetAttribute(“touch“)
end ]]
)
The first function creates a new button when called, and sets up certain
cosmetic details. The next block uses this function to create a button, and
attaches it to the rightmost extra action bar at the top end. Then it sets up a
Chapter 25 Taking Protected Action in Combat 479
snippet to handle clicks on the button, decreasing the effective page number
of the action bar. Finally, it does something similar to create another button,
attached to the bottom of the action bar, which increases the bar’s page number
by one. You now can rotate the rightmost extra action bar through all six action
pages independently of the main bar.
Take a particular look at a few parts of the snippet. The first line looks for
a frame handle to the button’s own parent (MultiBarRight) if necessary and
caches it in a private global to save on future lookups (because these buttons
will never change parents, this is fine; for a mod like BlessedMenus,avoid
caching parents for frames whose parentage can change dynamically). The
next part is the main logic; it uses :GetAttribute() on the parent frame handle
to determine the bar’s current page, and advances it to the next page, rotating
back to the other end of the cycle if needed. It also uses :SetAttribute() to
change the bar to the newly chosen page.
The last part uses :GetChildren() if needed to cache a list of the buttons
on the bar, and iterates across them, setting the touch attribute to nil.Thisis
done in order to trigger ActionBarButtonTemplate’s <OnAttributeChanged>
handler and cause it to refresh the buttons.
Allowed Actions
Using frame handles is intended to be as much like using frames as possible.
All of the following methods work on frame handles in basically the same way
as they do on frames, except that they throw an error if used on an unprotected
frame in combat (frames that are protected by virtue of having a protected
child still count as protected for most purposes here):
GetID() IsShown() IsVisible()
GetWidth() GetHeight() GetRect()
GetScale() GetEffectiveScale() GetFrameLevel()
GetAttribute(name) GetChildren() GetParent()
GetNumPoints() GetPoint(i) SetID(id)
SetWidth(width) SetHeight(height) SetScale(scale)
SetAlpha(alpha) ClearAllPoints() SetAttribute(name, value)
Raise() Lower() SetFrameLevel(level)
Disable() Enable() GetName()
IsProtected() GetObjectType() IsObjectType(ot)
All of these function work even on unprotected frames in combat, and can
be used to avoid errors caused by using disallowed frame handles.
Additional or Changed Actions
Several frame handle methods are exclusive to frame handles, or require
special considerations when used on frame handles.
480 Part III Advanced Addon Techniques
Show(skipAttr)
Hide(skipAttr)
By default, these methods of frame handles set or clear the statehidden
attribute, which is used by a few other parts of the UI. You can pass
true to these functions to prevent them from changing this attribute.
SetPoint(point, relframe, relpoint, xofs, yofs)
You can’t omit the relframe argument to assume the frame parent
when calling SetPoint from a snippet, although you can pass the
“$parent“ string instead of a frame handle. You also can’t omit the
relpoint argument if you want to pass any offset values.
relframe should be one of the following:
A valid handle to an explicitly protected frame (effective protection
is not sufficient)
nil or the string “$screen“ to anchor to the root window
The string “$parent“ to anchor to the frame’s parent
The string “$cursor“, which will place the frame offset from the
cursor’s position when the call is made. The frame will not automati-
cally track the cursor.
SetAllPoints(relframe)
This is subject to most of the same changes as SetPoint(),but
“$cursor“ is not a valid target.
SetParent(handle)
Like SetPoint(), the handle passed as the new parent must be an
explicitly protected frame.
GetFrameRef(label)
This method is only available to frame handles, because it’s not very
useful for normal frames. It returns the frame handle stored in
self:GetAttribute(“frameref-“..label). It’s generally used as a
convenient way to retrieve frame references passed in using
SecureHandlerSetFrameRef.
GetEffectiveAttribute(name, button, prefix, suffix)
This is used as an interface to SecureButton_GetModifiedAttribute,to
retrieve attributes that vary based on modifier keys and mouse button
the way SecureActionButtonTemplate does. You can omit some of the
arguments to search attributes based on the current system status.
GetChildList(tbl)
This is used to conserve memory and performance when you
frequently need to re-create a list of a frame’s children. It appends the
Chapter 25 Taking Protected Action in Combat 481
frame’s children to the table passed in and returns it again for
convenience. It does not purge the old contents automatically, but you
can run the table through table.wipe to do so before passing it in if
you need to.
GetMousePosition()
This returns the cursor’s current position over the frame, normalized to
the frame; that is, (0,0) is the frame’s lower left and (1,1) is its upper
right. If the mouse is not over the frame, this method returns nil.
IsUnderMouse(recursive)
This returns true if the frame is under the current mouse position. If
you pass true for recursive, it will also return true if any of the
frame’s children are under the mouse.
SetBindingClick(priority, key, name, button)
SetBinding(priority, key, action)
SetBindingSpell(priority, key, spell)
SetBindingMacro(priority, key, macro)
SetBindingItem(priority, key, item)
ClearBinding(key)
ClearBindings()
These are analogous to the SetOverrideBinding* functions in the
global environment, except that they are described as frame methods.
The calling frame is considered the owner of the override binding so
established.
An override binding is a temporary binding that does not affect your
saved key binding settings. It lasts until cleared or until the client is
closed or the UI reloaded. When a key is pressed, the client searches
first for the most recent override binding set with the priority argument
true, if any exist; if none are still assigned, it looks for the most recent
override binding assigned without priority. If no override bindings are
found for that key, the regular binding, if any, is triggered.
RegisterAutoHide(duration)
UnregisterAutoHide()
AddToAutoHide(handle)
These methods are usually used to support ‘‘hesitating menus,’’ menus
that automatically close after a brief time if a selection isn’t made from
them. RegisterAutoHide(duration) indicates that the frame should be
hidden duration seconds after the mouse leaves it, unless the mouse
reenters it during that time, in which case the timer starts again when
the mouse leaves the area. UnregisterAutoHide() simply cancels any
pending hide delay on the frame.
482 Part III Advanced Addon Techniques
AddToAutoHide(handle) includes handle’s screen area in the block that
will be monitored to determine if the mouse focus is on the frame or its
other points of interest, in order to determine if the timer will run down
or not. For instance, it allows a frame to stay visible as long as the
mouse is over it or any of its children.
Wrapping Frame Scripts
Suppose for a moment you’re leveling a druid, and running a lot of dungeons
like Razorfen Downs for gear and experience because you have a regular
group. Before every trip into a dungeon, and every so often while you’re
inside, you recast Mark of the Wild or Thorns on the whole group. This task
is repetitive and kind of mindless, so you might want to make an addon that
will make it easier (if you don’t have a druid, mages and priests also tend to go
through the same thing until they’re high enough to learn group buff spells).
The foundation of this frame, BuffCycler, is very simple, based on what you
learned in Chapter 15 about action buttons. Run the following lines in-game:
local BuffCycler = BuffCycler or CreateFrame(“Button“, “BuffCycler“, i
UIParent, “ActionButtonTemplate,SecureActionButtonTemplate“)
BuffCyclerIcon:SetTexture[[Interface\Icons\Spell_Nature_Regeneration]]
BuffCycler:SetAttribute(“type“, “spell“)
BuffCycler:SetAttribute(“spell“, “Mark of the Wild“)
BuffCycler:SetPoint(“TOPRIGHT“, BuffFrame, “TOPLEFT“, -300, 0)
Of course, in its current form, this addon button only casts Mark of the Wild
on your current target. Figure 25-2 shows the BuffCycler button in-game.
Figure 25-2: BuffCycler
Chapter 25 Taking Protected Action in Combat 483
A Simple Click Wrapper
If you’re familiar with making macros, you may already have learned that
cycling reliably through a set of targets isn’t the sort of thing that macros can
do easily or well. But programmatic logic doesn’t have much of a problem
with it, provided it’s allowed to work in combat. You can add that behavior to
the button with a function called SecureHandlerWrapScript:
SecureHandlerWrapScript(BuffCycler, “OnClick“, BuffCycler, [[
local unit = self:GetAttribute(“unit“)
if unit == “player“ then
unit = “party1“
elseif unit == “party1“ then
unit = “party2“
elseif unit == “party2“ then
unit = “party3“
elseif unit == “party3“ then
unit = “party4“
elseif unit == “party4“ then
unit = “player“
end
if unit and UnitExists(unit) then
self:SetAttribute(“unit“, unit)
else
self:SetAttribute(“unit“, “player“)
end
]])
What this code effectively does is ‘‘hook’’ BuffCycler’s OnClick handler with
the code in the long brackets, so that that code is called before SecureAction
Button_OnClick. The secure handler mechanisms create the hook as secure
code, so that it will not taint the call to SecureActionButton_OnClick.Youcan
also supply a second string (not used in this case) to be called as a ‘‘post-hook,’’
which is why it’s referred to as ‘‘wrapping’’ the existing script. These hooks
can be used in a number of ways:
As used here, they can set up the button’s functional attributes to prepare
it for its click, as well as internally recording information about the ‘‘state’’
of the addon, such as where it is in a series of actions.
A pre-hook snippet can use the return statement to modify the argument
values passed to the original frame script. For instance, because a click
handler takes button as an argument, a wrapper around OnClick can
return changed values for button to be used by the original handler when
it gets called.
A pre-hook snippet can also return false to completely suppress the
original handler from running. It can do this conditionally based on
484 Part III Advanced Addon Techniques
things like frame attributes or previously stored information, as well as
current API checks of approved information, such as whether you have a
target, or other legitimate macro conditions.
Notice that the SecureHandlerWrapScript call refers to BuffCycler twice.
When you call SecureHandlerWrapScript, you have to give it two frames,
which can be the same or different frames. The first one is the frame whose
script handler you will actually wrap. The second one (the third argument) is
the ‘‘owner’’ of the script; any private variable references (explained in more
detail a little later in the chapter) are associated with that frame. All scripts
owned by a frame have access to all private variables created by any script
owned by that frame.
To prevent exploits, only an explicitly protected frame (one inheriting from
atemplatewiththeprotected=“true“ tag attribute) can be designated as a
script owner. Moreover, snippets wrapping a frame script will not be run if
the wrapped frame becomes unprotected, such as by having all its protected
children re-parented to other frames. Its original script will be run without
modification, and its wrappers will resume functioning if it becomes protected
again.
WARNING At the time of this writing, implicit protection is not sufficient to
allow script wrappers to run on a frame; any script wrappers on a frame that is not
explicitly protected will be created successfully, but will be silently ignored. It is
possible that a future version of the secure handlers will lift this restriction, but
until such a change is made, you can make protected proxy frames with suitable
scripts and have them manipulate references to the frames you want to control.
It is also possible to unwrap a script, so that it returns to its original
behavior. SecureHandlerUnwrapScript(wrappedFrame, scriptName) will
securely restore the original handler, and return the prebody snippet, owning
header frame, and postbody snippet, allowing you to put the wrapper back
on if needed.
Using a Post-Hook
If two strings are supplied to SecureHandlerWrapScript, the second one is a
post-hook snippet called after the original handler completes. Most pre-hooks
can include a message as an additional return value; if this message is non-nil,
the post-hook is called and receives the message as an additional argument.
Post-hooks are commonly used to perform clean-up or change an addon’s
state information after an action completes, setting it up for the next action.
You can use this to make the menu frames created by BlessedMenus act
more like conventional popup menus, closing after a choice is made from
them. Open up the BlessedMenus.xml file and find the first template,
BlessedMenusSpellButtonTemplate.LocateitsOnLoad handler and add the
following statement at the end of the handler:
Chapter 25 Taking Protected Action in Combat 485
SecureHandlerWrapScript(self, “OnClick“, self:GetParent(),
[[return nil, “closeMenu“]],
[[if message == “closeMenu“ then owner:Hide() end]]
)
A pre-hook is always required, partly because a post-hook will never be
called unless the pre-hook returns a message to call it with. In this case,
returning nil as the button value means that the button argument will be
passed unchanged to the original click script.
The post-hook snippet receives the same arguments as the pre-hook snippet
(but with any changes returned by the pre-hook snippet), plus one more,
message, which is largely irrelevant in this example. The other point worth
noting is the global value, owner. Each secure environment stores a reference
to the frame handle for the frame with which the environment is associated.
Because the menu containing the button is the header frame for the wrapping
snippets, owner always refers to it. This is the simplest way to allow the menu’s
buttons to close their containing menu.
Script Wrapper Reference
The scripts that can be wrapped are mostly the same ones found on
SecureHandler templates; they deal specifically with user interaction or pro-
tected triggers. The following scripts support secure wrappers, with the
following arguments to their pre-hook and post-hook snippets.
SCRIPT PRE-HOOK POST-HOOK
OnClick button, message =
preHook(self, button,
down)
postHook(self,
message, button, down)
OnDoubleClick button, message =
preHook(self, button,
down)
postHook(self,
message, button, down)
PreClick button, message =
preHook(self, button,
down)
postHook(self,
message, button, down)
PostClick button, message =
preHook(self, button,
down)
postHook(self,
message, button, down)
OnEnter allow, message =
preHook(self)
postHook(self,
message)
OnLeave allow, message =
preHook(self)
postHook(self,
message)
OnShow allow, message =
preHook(self)
postHook(self,
message)
OnHide allow, message =
preHook(self)
postHook(self,
message)
486 Part III Advanced Addon Techniques
OnDragStart varies postHook(self,
message, button)
OnReceiveDrag varies postHook(self,
message, button)
OnMouseWheel allow, message =
preHook(self, offset)
postHook(self,
message, offset)
OnAttribute
Changed
allow, message =
preHook(self, name,
value)
postHook(self,
message, name, value)
Pre-hook snippets wrapping OnDragStart and OnReceiveDrag are a little
more complicated than others because their return values can be used to
control the cursor contents. They can return false as other pre-hook snippets
can to suppress the original script, or they can return type information
in the same manner as the _ondragstart and _onreceivedrag snippets of
SecureHandlerDragTemplate. They can also return “message“ and a message
value to prompt a postHook to execute.
Triggered Changes
Of course, sometimes you need to trigger a snippet in response to something
other than user input; the situations in which you can do this are limited, to
prevent automation, but they do exist, supported by a mechanism called state
drivers.
State Drivers
A state driver is a set of commands to an internal manager that takes action
on that frame when one or more elements of the game state change. It works
similarly to a conditional clause in a macro, selecting an argument based on a
set of authorized conditions, and passing that argument to a specified action
on a frame, usually showing it, hiding it, or setting an attribute. They are
established with the RegisterStateDriver or RegisterUnitWatch functions.
For instance, execute the following code in-game:
run RegisterStateDriver(PlayerFrame, “visibility“, “[combat] show; hide“)
The stock player frame should disappear from the upper left. Do something
to enter combatsuch as start a dueland it should reappear, disappearing
automatically once combat is over. This works even for protected frames, as
you just saw; although, not surprisingly, you cannot register or change a state
driver during combat from insecure code.
Chapter 25 Taking Protected Action in Combat 487
“visibility“ is a special case. When you pass it as the second argument,
the frame will be shown whenever your conditions statement (the third argu-
ment) evaluates to “show“ and hidden whenever it evaluates to “hide“.Forany
other string stateName you pass as the second argument, the state driver will
set the attribute on the frame named “state-“..stateName to whatever string
the conditions evaluate to, provided that value has actually changed since the
last time (a full explanation of conditions is provided at the end of the section).
You can then set that frame to react to that attribute change by having it inherit
from SecureHandlerStateTemplate or SecureHandlerAttributeTemplate (in
the next section). If you want to remove state triggers from a particular frame,
you can use UnregisterStateDriver(frame, action) to remove a specific
one or UnregisterStateDriver(frame) to remove all of them.
TIP RegisterUnitWatch is a convenient, simplified interface to a common use
case, wanting a unit frame to hide or show according to whether its unit currently
exists, the way the stock target frame does. If you want the frame to be notified
without changing its visibility, you can call RegisterUnitWatch(frame, true)
and the driver will set the state-unitexists attribute on the frame to true or
false instead.
RegisterUnitWatch(frame, useState) is almost equivalent to being an alias
for a preconfigured call to RegisterStateDriver, although there are two
important distinctions; you cancel it with UnregisterUnitWatch,andifyoutrack
a frame with RegisterUnitWatch and change the frame’s unit attribute, it will
start dynamically tracking the new unit rather than requiring you to unregister and
reregister the state driver.
State Responders
To perform other secure actions in response to changes in a frame’s attributes
or visibility, various templates are available:
SecureHandlerShowHideTemplate
SecureHandlerAttributeTemplate
SecureHandlerStateTemplate
Responding to Show/Hide
SecureHandlerShowHideTemplate is the simplest, and useful because you can
use it to respond to any change in visibility, not just ones triggered by state
drivers. For instance, you can tweak BlessedMenus so that the menus close
when the user presses the Esc key.
Open BlessedMenus.lua and find the definition of the BlessedMenu function.
Change the first few lines as follows:
488 Part III Advanced Addon Techniques
local function BlessedMenu(name, ...)
local self = CreateFrame(Button“, name, nil, i
“BlessedMenusMenuTemplate“)
self.buttons = {}
Next, open BlessedMenus.xml and find the frame definition for
BlessedMenusMenuTemplate. First, find the protected=“true“ tag attribute on
the <Frame> tag and change it to inherits=“SecureHandlerShowHideTemplate,
SecureHandlerClickTemplate“. Then change the <Frame> tag itself and its
corresponding </Frame> tag to <Button> and </Button> tags. Finally, just
before the </Attributes> tag, add three more attribute definitions:
<Attribute name=“_onshow“ value=“self:SetBindingClick(false, i
’ESCAPE’, self:GetName(), 'Escape’)“ />
<Attribute name=“_onhide“ value=“self:ClearBindings()“ />
<Attribute name=“_onclick“
value=“if button == 'Escape’ then self:Hide() end“ />
XML doesn’t support long brackets, so you should be careful when writing
snippets to be stored in XML attributesfor example, by using single quota-
tion marks around strings within the snippet, since a double quotation mark
would be interpreted as the end of the XML attribute. If your code is more
complicated, such that avoiding quotation marks becomes an issue, you can
use :SetAttribute() calls in a frame’s or template’s OnLoad code instead of
specifying snippets in XML attributes.
This code modifies the frames used as menus by making them clickable. It
attaches secure code so that when the frame is shown, it will temporarily bind
the Escape key to click the menu itself (rather than its buttons) with the virtual
mouse button “Escape“ (because mouse clicks are represented to the UI using
strings, any string value can be used as a ‘‘button’’). When that click (and only
that click) happens on the menu, the menu will close itself. When the menu is
closed for any reason, it will give up its hold on the Escape key and return it
to its previous function.
Responding to Attribute and State Changes
SecureHandlerAttributeTemplate is a fairly straightforward template. It will
fire the frame’s _onattributechanged snippet whenever one of the frame’s
attributes (whose name does not start with an underscore) is changed,
supplying the name and value of the changed attribute as arguments.
SecureHandlerStateTemplate gives a little more structure to its use and is bet-
ter integrated with the state drivers. It is only triggered by changes in attributes
whose names start with “state-“. When one happens, it looks for a snippet in
the frame attribute with the same name as the changed attribute, but prefixed
Chapter 25 Taking Protected Action in Combat 489
with “_on“; that is, if triggered by a change to the state-unitexists attribute,
it looks for a snippet to handle that attribute in the _onstate-unitexists
attribute. Instead of the raw name and value arguments, it calls that snippet
with the stateid argument, which is the name of the changed attribute minus
the “state-“ portion, and the newstate argument, which is the same as value.
That is, if the state handler was triggered by a change in the state-unitexists
attribute, the stateid argument will be “unitexists“.
To see one rather remarkable way you can use SecureHandlerState
Template, enter the following block into a fresh page in-game (if you don’t
have a priest to test this with, substitute spells or items appropriate to your
character):
local self = AvatarCaster or CreateFrame(“Button“, “AvatarCaster“, i
nil, “SecureActionButtonTemplate,SecureHandlerStateTemplate“)
self:Hide()
self:SetAttribute(“_onstate-mouseover“, [[
if newstate == “exists“ then
local name = self:GetName()
self:SetBindingClick(false, “SHIFT-BUTTON1“, name, “shift1“)
self:SetBindingClick(false, “CTRL-BUTTON1“, name, “ctrl1“)
self:SetBindingClick(false, “SHIFT-BUTTON2“, name, “shift2“)
self:SetBindingClick(false, “CTRL-BUTTON2“, name, “ctrl2“)
else
self:ClearBindings()
end ]]
)
RegisterStateDriver(self, “mouseover“, i
“[target=mouseover,exists] exists; noexists“)
self:SetAttribute(“unit“, “mouseover“)
self:SetAttribute(“type“, “spell“)
self:SetAttribute(“*spell-shift1“, “Power Word: Fortitude“)
self:SetAttribute(“*spell-shift2“, “Power Word: Shield“)
self:SetAttribute(“*spell-ctrl1“, “Flash Heal“)
self:SetAttribute(“*spell-ctrl2“, “Renew“)
Run this script once you’ve finished it. Try holding down Shift or Control
and clicking various character or monster avatars in the game-world display;
observe how spells are cast on them directly without changing your target.
Now, you can break down how it works.
The frame is created from a combination of SecureActionButtonTemplate
(so that it can actually cast spells) and SecureHandlerStateTemplate (so that
it can respond to changes in the game state). The AvatarCaster or portion
simply prevents you from creating a new frame if you need to run the script
more than once, such as by making an error in the script the first time. The
490 Part III Advanced Addon Techniques
frame is purely functional, and requires no visual presentation such as textures
or font strings.
The _onstate-mouseover snippet will be called whenever the
state-mouseover attribute is set, with “mouseover“ as the stateid
argument and the new value of the attribute as the newstate argument.
Because this snippet is only being used for one state variable, it disregards
the stateid argument. If state-mouseover is set to “exists“, the button will
rebind several mouse clicks so that they ‘‘click’’ this action button even though
the mouse is no longer over it. These bindings do not replace any standard
bindings associated with these button clicks; instead, they are ‘‘owned’’ by
the frame whose handle sets them, and last until the frame releases them (as it
does when the snippet is called with “noexists“).
Rather than standard values such as “LeftButton“, the button argument
received by the button’s OnClick handler will be a special value such as
“shift1“. This workaround is need to preserve information about which
modifiers were down when the click was made, because when a binding that
includes modifiers, such as SHIFT-F1, is pressed, the binding’s actual code is
resolved as if Shift (or whatever modifiers are included in the binding) were
not being held down; this prevents the action button from finding traditional
modified attributes such as shift-spell1.
The RegisterStateDriver call establishes a driver so that when your
mouse cursor is pointing at a targetable player or creature, the button’s
state-mouseover attribute will be set to either “exists“ or “noexists“,
accordingly. It will not actually set the frame’s attribute value if the new
value would be the same as the old value, so the frame’s _onstate-mouseover
snippet will only be called when it actually changes.
The last block of code sets up the spellcasting characteristics of the button,
as explained in Chapter 15. Two points are worthy of note: the button’s unit
is “mouseover“, so that spells will be cast on whatever player or mob is under
the mouse in the world frame; and the attributes are phrased to key off of the
custom button values supplied by the SetBindingClick calls in the previous
code snippet.
State Conditionals
The key to registering state drivers that actually do what you want is under-
standing the conditional system. If you are familiar with writing macros, you
have likely seen it already; macros that select a spell based on modifier keys
or the nature of the target rely on the same system. When you give it a string,
it returns a portion of that string based on the game state by calling a function
called SecureCmdOptionParse.
This function starts at the beginning of the string and looks for the first
matching pair of square brackets ([]) and anything they contain. If it does not
Chapter 25 Taking Protected Action in Combat 491
find a pair of brackets, it goes to either the first semicolon it finds, if there is
one, or the end of the string, if there isn’t, and returns everything from where
it is up to that point, trimming off any leading or trailing whitespace. If it does
find such a pair, it separates the contents into a series of conditions wherever it
finds commas, and determines the truth value of each condition. If all of them
are true, it looks for either the next semicolon after the end bracket, or the end
of the string, and returns anything before the point it finds, starting from the
last closing square bracket before that point, again trimming off any leading
or trailing whitespace. If any of the conditions are false, it repeats its search,
starting from after the ending bracket of the set of conditions it just checked.
Figure 25-3 shows the breakdown of parsing a secure command.
Figure 25-3: Breaking down conditionals
A comprehensive list (as of the time of this writing) of recognized conditions
follows. The system is case-sensitive; conditions must be in lowercase to be
recognized, except for the names of spells, units, or creature types, for which
case is disregarded. If a condition is encountered that is not recognized, it is
automatically treated as being false, and a system message appears in your
chat window indicating that an unknown macro option was encountered and
what it was. A recognized condition prefaced with no is also a valid condition,
meaning the opposite of what the condition tests for; for instance, [nocombat]
returns true if you are not in combat.
Target Specifiers and Unit Conditions
Although most conditions, such as [combat], are general inquiries about the
player’s game state, certain conditions apply to a specific unit, such as [dead].
By default, such conditions refer to the player’s current target; but if you want
to ask about the status of another unit, you can include a [target=unitID]
clause in your conditions. By itself, a [target=unitID] specifier is always
true; this is useful in many macros (because in a macro, such a specifier
will also redirect a spell or item being cast to its unit), but not in state
driver conditionals. However, they still have many uses in state drivers when
combined with specific unit conditions, such as [target=mouseover,exists]
in the AvatarCaster example earlier.
Any acceptable unitID can be supplied. Remember that names of pets or
characters in your raid or party are also valid unitIDs, but names of mobs,
totems, enemies, or allied players outside your group are not.
492 Part III Advanced Addon Techniques
State Variables
Some conditions can have more than one value. For instance, [modifier] is
true if any of the Ctrl, Shift, and Alt keys are held down, but [modifier:ctrl]
is true only if the Control key, specifically, is down, whether or not other
modifier keys are down.
A state variable can be checked for more than one possible value by stringing
them together; for example, [modifier:shift/alt] is true if either the Shift
or the Alt key is down. If you negate this condition, first the whole condition
is evaluated, then the result is negated, so [nomodifier:shift/alt] is true if
neither the Shift key nor the Alt key is down. This means that if you want to
test if the Control key and only the Control key is being held, you can use the
compound condition [modifier:ctrl, nomodifier:shift/alt].
Some condition variables can be checked meaningfully without checking
them for a particular value; that is, [channeling] is true if you are presently
channeling any spell, but [channeling:Blizzard] is only true if you are
particularly channeling the Blizzard spell. However, some condition variables
always have a value, so you must specify one or more values to get a
meaningful result. [actionbar:3] is only true if your main action bar is set to
page 3, but [actionbar] is always true, because you are always on some page
or another.
Unit Conditions
The following conditions are tested against your target, unless you specify
another target using a [target=unitID] phrase:
[exists]Indicates whether the unit exists, regardless of its condition.
So [noexists] will be true if you have no target.
[harm]Indicates that the unit exists and that you are able to cast attack
spells on it. So [target=focus,noharm] means that either you have no
focus or that it is not attackable.
[help]Indicates that the unit exists and that you could target it with
beneficial spells such as buffs or heals. It is possible, although very
uncommon, for both [help] and [harm] to be true for a given unit; it is
more common for both [noharm] and [nohelp] to be true for a unit, such
as certain NPCs; and naturally, if [noexists] is true for a unit, then both
[nohelp] and [noharm] will also be true.
[dead]True if the unit exists and is dead or a ghost. Currently, [nodead]
is usually more functional, and usually needs to be in a [exists,nodead]
clause to be useful.
[party] and [raid]True if the target is in the same party or raid with
you, respectively. If [party] is true, [raid] will also be true, but not
Chapter 25 Taking Protected Action in Combat 493
always the other way around. Be careful not to confuse these conditions
with [group:party] and [group:raid], described later.
General Conditions
These conditions always apply to the condition of the player character or the
client UI, regardless of which unit might be specified in the conditional clause.
Several of the following conditions have abbreviations or synonyms that you
can use if you need to make your code more concise:
[actionbar:1/2/3/4/5/6],[bar:1/2/3/4/5/6]These both return true
if the given page (or one of the given pages) is currently the active page in
the UI. In state drivers, this can be useful for synchronizing two or more
action bars together so that one changes when another does.
[bonusbar:1/2/3/4/5]Used to handle special additional action bar
pages such as those provided when a warrior switches stances or when a
druid switches shapeshift forms. Assuming that the character has learned
all appropriate stances, forms, or similar capabilities, they are numbered
as shown in Table 25-2.
Table 25-2: Bonus Bar Values for Various Classes and Modes
BONUS BAR WARRIOR DRUID ROGUE PRIEST/WARLOCK
1 Battle
Stance
Bear Form/
Dire Bear
Form
Stealth Shadowform or
Metamorphosis
2 Defensive
Stance
Cat Form Shadow
Dance
3 Berserker
Stance
Moonkin
Form/Tree
of Life Form
There are two other numbers: 4, which is presently not used by the stock
UI, and 5, a special case available to all players, used when you are
possessing another unit or controlling a vehicle.
[button:1/.../5/<virtual click>],[btn:1/.../5/<virtual
click>]Because it selects based on what mouse button was clicked on
an action button to trigger the current action, this option is very useful in
macros, but is almost totally purposeless for use in state drivers.
[channeling],[channeling:<spell name>{/<spell name>}]—In its
general form, this condition is true if the player is channeling any spell;
494 Part III Advanced Addon Techniques
with a value or list of values, it is true while the player is channeling any
of the listed spells.
[combat]True whenever the player character or his pet is engaged in
combat.
[equipped:<item type>],[worn:<item type>]True if the player char-
acter has an item that is of the given type or subtype equipped and
equipped in the given inventory slot.
It can check for any of the following item types or subtypes; it cannot
check for a specific item by name:
Arrow Leather Shields
Bullet Librams Staves
Bows Mail Thrown
Cloth Miscellaneous Totems
Crossbows One-Hand Two-Hand
Daggers One-Handed Axes Two-Handed Axes
Guns One-Handed Maces Two-Handed Maces
Fishing Poles One-Handed Swords Two-Handed Swords
Fist Weapons Plate Wands
Idols Polearms
[flyable]Returns true if the player is in an area where flying is
allowed. This also returns true even if the player lacks a skill needed to
fly in that area.
[flying]True if the player is flying; that is, off the ground on a flying
mount or in a flying form. It is not true when the character is in the air
because he is jumping or falling, even with a slow fall effect.
[group],[group:party],[group:raid][group] is true when you are
in any kind of group; [group:raid] is true whenever you are in
any kind of raid group, including battlegrounds. [group:party] and
[group:party/raid] are legal syntax, but are both effectively longer
synonyms for [group].
[indoors]True whenever the player is indoors.
[modifier:shift/ctrl/alt/<MODIFIEDCLICK>],[mod:shift/ctrl/
alt/<MODIFIEDCLICK>][modifier] and [mod] by themselves are true
whenever the player is holding any of the Shift, Control, or Alt keys
down. With a specified key or list of keys, they are true whenever any of
thespeciedkeysaredown.
This condition also supports abstract, rebindable modifiers such as
SELFCAST (which defaults to the Alt key). See the IsModifiedClick and
SetModifiedClick functions (API) for more information.
Chapter 25 Taking Protected Action in Combat 495
[mounted]True whenever the player character is on any kind of mount,
including automated flight path (taxi) mounts, but typically not when
operating a vehicle.
[outdoors]True whenever the player character is outdoors. It uses a
separate API from [indoors] (pertaining to the usability of certain spells
and items, which does not necessarily correspond to whether a roof is
over the player’s head), so it is not always synonymous with [noindoors],
although this will generally be the case.
[pet],[pet:<pet name>],[pet:<pet type>][pet] is true whenever
the player character is controlling a pet of any kind, including a vehicle
or possessed unit. With an argument or list of arguments, it is true if the
player character is controlling a pet whose name or type (such as owl or
succubus) matches any of the listed arguments.
[spec:n]True if the player character’s currently active talent special-
ization index is in the list of arguments. At the time of this writing, only
the values 1 and 2 are possible, but this could be expanded at some point
in the future.
[stance],[form],[stance:0/1/2/.../n],[form:0/.../n]—By itself,
[stance] or [form] returns true if the player character is in any stance
or shapeshift form; this will always be true for warriors. With a list of
numerical arguments, it is true when the player character’s current stance
or form index is in the argument list. Table 25-3 shows the possible
indices, depending on class:
Table 25-3: Stance Values for Different Classes
INDEX WARRIOR DRUID ROGUE PRIEST SHAMAN WARLOCK
1 Battle
Stance
Bear
Form/Dire
Bear Form
Stealth Shadow
form
Ghost
Wolf
2 Defensive
Stance
Aquatic
Form
Metamor-
phosis
3 Berserker
Stance
Cat Form Shadow
Dance
4TravelForm
Druid stance values are a bit more complicated because, due to talents, the
player might have Tree of Life form or Moonkin Form. In that case, stance 5
will contain this form, and stance 6 will contain the player’s flight form (either
Flight Form or Swift Flight Form). If the player does not have either of those
talented stances, the flight forms will be moved into stance 5.
496 Part III Advanced Addon Techniques
This condition is closely related, but not identical, to [bonusbar].
[stealth]True if the player character is in any kind of stealth condition,
including rogue stealth, druid prowl, night elf shadowmeld, or mage
invisibility. There is presently no way to determine if a hunter pet is in
stealth from the conditional system.
[swimming]True whenever your character is in the water.
Summary
This chapter addresses quite a lot of material, but fortunately most of it is
based on a few common principles. By now, you should grasp how to:
Write snippets that use implied arguments, private globals, frame han-
dles, and a restricted environment.
Attach these snippets to frames for secure execution by using
SecureHandler templates or script wrappers.
Register state drivers to take action on frames, and construct conditionals
that will select the values you want to use based on game state.
The Code
BlessedMenus
BlessedMenus.toc
## Interface: 30300
## Title: BlessedMenus
## Notes: Creates menus on party frames to select spells to cast on them
BlessedMenus.xml
BlessedMenus.lua
BlessedMenus.xml
<Ui xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Button name=“BlessedMenusSpellButtonTemplate“ enableMouse=“true“ i
inherits=“SecureActionButtonTemplate“ virtual=“true“>
<Size x=“144“ y=“16“ />
<Layers>
Chapter 25 Taking Protected Action in Combat 497
<Layer level=“ARTWORK“>
<Texture parentKey=“icon“>
<Size x=“16“ y=“16“ />
<Anchors>
<Anchor point=“TOPLEFT“ />
</Anchors>
</Texture>
</Layer>
</Layers>
<Attributes>
<Attribute name=“type“ value=“spell“ />
<Attribute name=“useparent-unit“ value=“true“ type=“boolean“ />
</Attributes>
<Scripts>
<OnLoad>
SecureHandlerWrapScript(self, “OnClick“, self:GetParent(),
[[return nil, “closeMenu“]],
[[if message == “closeMenu“ then owner:Hide() end]]
)
self:GetFontString():SetPoint(“LEFT“, self.icon, “RIGHT“, 2, 1)
self:RegisterEvent(“PLAYER_ENTERING_WORLD“)
</OnLoad>
<OnEvent>
self.icon:SetTexturei
(GetSpellTexture(self:GetAttribute(“spell“)))
</OnEvent>
</Scripts>
<ButtonText inherits=“GameFontHighlight“ justifyH=“LEFT“ />
<HighlightTexture alphaMode=“ADD“>
<Color r=“0.75“ g=“0.75“ b=“0.6“ a=“0.5“ />
</HighlightTexture>
</Button>
<Button name=“BlessedMenusMenuTemplate“ hidden=“true“ i
inherits=“SecureHandlerShowHideTemplate,SecureHandlerClickTemplate“ i
virtual=“true“>
<Size x=“160“ y=“18“ />
<Backdrop bgFile=“Interface\Tooltips\UI-Tooltip-Background“ i
edgeFile=“Interface\Tooltips\UI-Tooltip-Border“ tile=“true“>
<EdgeSize val=“16“/>
<TileSize val=“16“/>
<BackgroundInsets left=“4“ right=“4“ top=“4“ bottom=“4“/>
<BorderColor r=“1“ g=“1“ b=“1“ />
<Color r=“0.09“ g=“0.09“ b=“0.19“ />
</Backdrop>
<Attributes>
<Attribute name=“useparent-unit“ value=“true“ type=“boolean“ />
<Attribute name=“_onshow“ value=“self:SetBindingClick(false, i
’ESCAPE’, self:GetName(), 'Escape’)“ />
<Attribute name=“_onhide“ value=“self:ClearBindings()“ />
<Attribute name=“_onclick“
498 Part III Advanced Addon Techniques
value=“if button == 'Escape’ then self:Hide() end“ />
</Attributes>
</Button>
</Ui>
BlessedMenus.lua
local function BlessedMenu(name, ...)
local self = CreateFrame(“Frame“, name, nil, i
“BlessedMenusMenuTemplate“)
self.buttons = {}
for i=1, select(’#’, ...) do
local spellName = select(i, ...)
local button = CreateFrame(“Button“, nil, self, i
“BlessedMenusSpellButtonTemplate“)
self.buttons[i] = button
button:SetAttribute(“spell“, spellName)
button:SetText(spellName)
if i == 1 then
button:SetPoint(“TOPLEFT“, 8, -8)
else
button:SetPoint(“TOPLEFT“, self.buttons[i - 1], “BOTTOMLEFT“, i
0, -2)
end
end
self:SetHeight(#self.buttons * 18 + 14)
return self
end
local heals = BlessedMenu(“BlessedMenusHeals“,
“Holy Light“,
“Flash of Light“,
“Lay on Hands“
)
local hands = BlessedMenu(“BlessedMenusHands“,
“Hand of Protection“,
“Hand of Freedom“,
“Hand of Salvation“,
“Hand of Sacrifice“
)
local blessings = BlessedMenu(“BlessedMenusBlessings“,
“Blessing of Might“,
“Blessing of Kings“,
“Blessing of Wisdom“
)
local openSpellList = [[
local menu = IsAltKeyDown() and “blessings“
Chapter 25 Taking Protected Action in Combat 499
or IsControlKeyDown() and “heals“
or IsShiftKeyDown() and “hands“
menu = menu and self:GetFrameRef(menu)
if lastMenu and lastMenu:IsShown() and i
lastMenu:GetParent() == self then
lastMenu:Hide()
if lastMenu == menu then
return
end
end
if menu then
menu:Hide()
menu:SetParent(self)
menu:SetPoint(“TOPLEFT“, “$cursor“)
menu:SetFrameLevel(self:GetFrameLevel() + 2)
menu:Show()
lastMenu = menu
end
]]
for i, frame in ipairs{PlayerFrame, PartyMemberFrame1, i
PartyMemberFrame2, PartyMemberFrame3, PartyMemberFrame4} do
frame:SetAttribute(“shift-type1“, “spelllist“)
frame:SetAttribute(“ctrl-type1“, “spelllist“)
frame:SetAttribute(“alt-type1“, “spelllist“)
frame:SetAttribute(“_spelllist“, openSpellList)
SecureHandlerSetFrameRef(frame, “blessings“, BlessedMenusBlessings)
SecureHandlerSetFrameRef(frame, “heals“, BlessedMenusHeals)
SecureHandlerSetFrameRef(frame, “hands“, BlessedMenusHands)
end
CHAPTER
26
Creating Unit Frames with
Group Templates
Earlier in this book you learned how to create a very simple unit frame, and
then later extended it by making it clickable using secure templates. With some
work, you could extend this addon to show your party or raid, but because
each individual frames is a secure template, it cannot be created or configured
while the player is in combat.
One way around this is to create all of the frames ahead of time and use
the ‘‘unit watch’’ system to show them as needed. For something like party
frames, this might even make the most sense, because you can create the
frames before the player enters combat, and the secure template system will
show and hide them as necessary. However, this method isn’t well suited to
displaying larger groups like raids.
What if you want to display your raid group and sort it by class or raid
role? This would allow you to always have the tanks in one location and the
unit frames of your healers in another. Unfortunately, there doesn’t seem to
be a way to do this in the default user interface. Luckily, Blizzard provides
several templates that allow developers to create raid, party, and pet frames
that update and configure themselves even while the player is in combat. The
templates allow you to pre-program the type and configuration of the frames,
as well as directions of how the frames should be placed and sorted.
In this chapter you use the SecureGroupHeaderTemplate to create a fully
functional party/raid unit frame addon called SquareUnitFrames.
Configuring a SecureGroupHeader
The role of the secure group headers is actually pretty straightforward,
managing only the parts that aren’t possible in addon code. The header’s
501
502 Part III Advanced Addon Techniques
primary responsibility is managing the creation and placement of frames. As
players join your party or raid, the secure template handles the creation of
new frames for each of them. If an addon were to try this while the player is
in combat, the new frames would be locked down, unable to be modified. The
group headers enable your addon to do last-minute configuration before the
frame is ever locked down.
The process for creating a new group header is roughly as follows:
1. Create a new header frame that inherits from SecureGroupHeader
Template. This may be a custom XML template that inherits from the
Blizzard template and adds things such as artwork and labels, or just the
raw template itself.
2. Set attributes on the new header for some of the following:
What characters, classes, groups should be displayed in the header?
Should the header be displayed when the player is in a party, raid,
solo, or all of the above?
When new frames are created, how should they be anchored to the
existing frames?
How should the frames be sorted?
Should the frames be grouped, or displayed in columns and rows?
3. Supply an XML template (optionally) that the header will use to create
new unit frames. Again, this could just be the standard SecureUnitButton
or a custom template with artwork and other elements.
4. Provide a configuration function (optionally) that will be called when
a new unit frame is created, allowing for last-minute customization by
addons.
Of course, creating a fully functional raid addon is a bit more complicated
than this, but once you’ve mastered the basics of using the template, other
features can be added to your addon as necessary.
Configuration Options
ASecureGroupHeader has plenty of options that can be set using attributes.
These options can be grouped into three major classes: filtering, grouping and
sorting, and display. Tables 26-1, 26-2, and 26-3 describe these attributes.
When specifying a groupBy attribute, you must also supply a groupingOrder
or the template will encounter an error, because groupingOrder doesn’t have
any default values.
Chapter 26 Creating Unit Frames with Group Templates 503
Table 26-1: Filtering Attributes
ATTRIBUTE TYPE DESCRIPTION
showRaid boolean When true, the group header is shown when
the player is in a raid.
showParty boolean When true, the group header is shown when
the player is in a party. This attribute doesn’t
imply showRaid but can work alongside it.
showPlayer boolean When true, the header includes the player
when not in a raid (normally, the player would
not be visible in a party listing).
showSolo boolean When true, the header is shown when the
player is not in any group. This option implies
showPlayer.
nameList string A comma-separated list of player names to be
included in the listing. This option is not used if
groupFilter is specified.
groupFilter string A group number, or any combination of the
following strings:
A comma-separated list of raid group
numbers
A comma-separated list of uppercase class
names in English (WARRIOR,PRIEST,and
so on)
A comma-separated list of uppercase
group roles (MAINTANK,MAINASSIST)
strictFiltering boolean When true, a character must match both a
group and a class from the groupFilter list.
This allows you to specify “1,WARRIOR“,which
shows all warriors in group 1.
Table 26-2: Grouping and Sorting Attributes
ATTRIBUTE TYPE DESCRIPTION
groupBy string Specifies a grouping to apply before the list of
players is sorted. Can be one of the following
values: “GROUP“,“CLASS“,or“ROLE“.The
sorting within these groups can be specified
with the groupingOrder attribute.
Continued
504 Part III Advanced Addon Techniques
Table 26-2 (continued)
ATTRIBUTE TYPE DESCRIPTION
groupingOrder string Specifies what order should be applied to the
groups before they are sorted individually. This
should be a comma-separated string of group
numbers, uppercase class names, or uppercase
role names (depending on what type of
grouping was specified).
sortMethod string Specifies what sorting method should be used
for ordering raid frames. Can be either “NAME“
or “INDEX“, where index will sort the raid by
the internal raid ID. This value defaults to
“INDEX“.
sortDir string Specifies the sort order using “ASC“ for
ascending, and “DESC“ for descending. This
value defaults to “ASC“.
Table 26-3: Display Attributes
ATTRIBUTE TYPE DESCRIPTION
template string The name of an XML template to use when
creating new frames. This can be a custom
template, or the simple
SecureUnitButtonTemplate.
templateType string The frame type of the XML template being used
(Button,StatusBar, and so on).
point string A valid XML anchor point. This point will be
used to anchor a new frame to an existing
frame. The code will intelligently use the
opposing anchor points, so if you specify
“TOP“, it will anchor the “TOP“ point of the
new frame to the “BOTTOM“ point of the
previous frame.
xOffset number An xoffset (in pixels) to be used when
anchoring new frames.
yOffset number A yoffset (in pixels) to be used when
anchoring new frames.
maxColumns number The maximum number of columns that the
header will create. The default for this attribute
is a single column.
Chapter 26 Creating Unit Frames with Group Templates 505
ATTRIBUTE TYPE DESCRIPTION
unitsPerColumn number The maximum number of units that will be
displayed in a single column. When this value is
nil, there is no limit.
startingIndex number The index in the final sorted list at which to start
displaying units. This value defaults to 1.
columnSpacing number The amount of space (in pixels) between the
columns. This value defaults to 0.
columnAnchorPoint string The anchor point for each new column. A value
of “LEFT“ causes the columns to grow to the
right.
initial-anchor string The initial anchor point for new unit frames.
Thiscanbeusedtoplacetheframeina
different starting location (such as growing from
the bottom up instead of top down). This value
should be a comma-separated list containing
anchor point, relative anchor point, x offset, and
yoffset.
initial-width number The initial width of the unit frame in pixels.
initial-height number The initial height of the unit frame in pixels.
initial-scale number The initial scale of the unit frame.
Initial-unitwatch boolean Whether or not the frame should register for
unit watch when initially created. If this
attribute is set to the string state, the frame will
be notified via the wattribute. If this attribute is
set to any other true value, the frame will be
shown or hidden depending on whether or not
the unit exists.
In Table 26-3, a column means the initial level of grouping for the raid
frames. Because you can specify a custom anchor point for the frames (using
the point attribute), your columns could actually be horizontal, and your rows
could be vertical. In addition, when using a multicolumn display, you must
specify a columnAnchorPoint or the template will generate an error.
Initial Configuration Function
In addition to the predefined attributes, a group header can identify an
initial configuration function that will be called after a frame has been cre-
ated, but before it is fully locked down by the user interface. Setting the
506 Part III Advanced Addon Techniques
initialConfigFunction key in the header’s table to a function enables this
feature.
This function will be able to set attributes on the frame and do any other
one-time configuration bits. This is a good chance to register events and
click handlers, or set up any secure click actions. Although the frame is not
completely locked down, you are still unable to move/hide/show the frame
from within this function.
Creating SquareUnitFrames
As with all of your addons, start by creating an addon skeleton called
SquareUnitFrames, containing both a Lua and an XML file. Create
SquareUnitFrames.toc and add the following:
## Interface: 30300
## Title: SquareUnitFrames
## Notes: Square shaped party/raid frames
SquareUnitFrames.xml
SquareUnitFrames.lua
Constructing the Template
AnormalSecureUnitButton won’t have any visual elements and you know
you want to display at least the unit’s name, health, and power. Open up
SquareUnitFrames.xml and include the following code to define the button
template:
<Ui
xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Frame name=“SquareUnitFrames_UnitTemplate“ virtual=“true“>
<Size x=“36“ y=“36“/>
<Layers>
<Layer level=“BACKGROUND“>
<Texture setAllPoints=“true“>
<Color r=“0.0“ g=“0.0“ b=“0.0“/>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnShow function=“SquareUnitFrames_Frame_OnShow“/>
</Scripts>
</Frame>
</Ui>
Chapter 26 Creating Unit Frames with Group Templates 507
This code creates a new template called SquareUnitFrames_UnitTemplate
that will be used by the group header to create new frames. The template
defines a solid black background texture, sized 36-by-36 pixels. The rest of the
sub-frames will be children of this main frame.
After the </Layers> tag and before the <Scripts> tag, add the following
frame definitions:
<Frames>
<Button name=“$parent_Unit“ parentKey=“unit“ i
inherits=“SecureUnitButtonTemplate“>
<Size x=“34“ y=“34“/>
<Anchors>
<Anchor point=“TOPLEFT“>
<Offset x=“1“ y=“-1“/>
</Anchor>
</Anchors>
<Layers>
<Layer level=“OVERLAY“>
<FontString name=“$parent_Name“ parentKey=“name“
inherits=“GameFontHighlight“ setAllPoints=“true“/>
</Layer>
</Layers>
<Frames>
<StatusBar name=“$parent_HealthBar“ parentKey=“healthBar“>
<Size x=“34“ y=“30“/>
<Anchors>
<Anchor point=“TOPLEFT“/>
</Anchors>
<BarTexture file=“Interface\Buttons\UI-Listbox-Highlight2“/>
<BarColor r=“1.0“ g=“1.0“ b=“1.0“/>
</StatusBar>
<StatusBar name=“$parent_PowerBar“ parentKey=“powerBar“>
<Size x=“34“ y=“3“/>
<Anchors>
<Anchor point=“TOPLEFT“ relativeTo=“$parent_HealthBar“
relativePoint=“BOTTOMLEFT“>
<Offset x=“0“ y=“-1“/>
</Anchor>
</Anchors>
<BarTexture file=i
“Interface\TargetingFrame\UI-TargetingFrame-BarFill“/>
<BarColor r=“1.0“ g=“1.0“ b=“1.0“/>
</StatusBar>
</Frames>
</Button>
</Frames>
This first sub-frame is the actual button that displays the unit’s name, health,
and power (for example, mana, rage, or energy). The button is anchored and
508 Part III Advanced Addon Techniques
sized in a way that causes the background to appear as a one-pixel border on
all sides. The textures used here were chosen for a specific visual style, but
you could use any texture for your status bars. The health bar dominates most
of the frame, whereas the power bar is just 3 pixels high.
Creating a Header Template
Although you could create a header purely in Lua and set attributes on it in
your main script, setting the attributes in XML may be preferable because it
allows the frame to be validated as a whole (and remain alterable in Lua).
After the template definition in SquareUnitFrames.xml but before the </Ui>
tag, add the following code:
<Frame name=“SquareUnitFrames_Header“ parent=“UIParent“
inherits=“SecureGroupHeaderTemplate“ movable=“true“>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Attributes>
<Attribute name=“showParty“ type=“boolean“ value=“true“/>
<Attribute name=“showRaid“ type=“boolean“ value=“true“/>
<Attribute name=“showPlayer“ type=“boolean“ value=“true“/>
<Attribute name=“showSolo“ type=“boolean“ value=“true“/>
<Attribute name=“maxColumns“ type=“number“ value=“8“/>
<Attribute name=“unitsPerColumn“ type=“number“ value=“5“/>
<Attribute name=“columnAnchorPoint“ type=“string“ value=“TOP“/>
<Attribute name=“point“ type=“string“ value=“LEFT“/>
<Attribute name=“template“ type=“string“
value=“SquareUnitFrames_UnitTemplate“/>
<Attribute name=“templateType“ type=“string“ value=“Frame“/>
<Attribute name=“xOffset“ type=“number“ value=“-1“/>
<Attribute name=“yOffset“ type=“number“ value=“1“/>
</Attributes>
</Frame>
This new frame template inherits from SecureGroupHeaderTemplate and
begins anchored in the center of the screen. The attributes section programs
how the header is to behave. You learn more about each of the possible
attributes in the next section but for now, know that this frame will include the
player in its display, and will be shown when the player is in a raid, in a party,
or soloing. Frames are organized into columns of five, with eight columns
total. The grid of frames groups from left to right and the template you’ve just
denedisusedtocreatethechildframes.
Because each frame has a one-pixel black border, two frames stacked
vertically would have two pixels in between, and a one-pixel border around.
To prevent this and make the borders consistent, xOffset and yOffset are set
to tell the header how to anchor new frames.
Chapter 26 Creating Unit Frames with Group Templates 509
Additionally, the header is flagged as movable, because at some point in the
futureitmaybeusefulfortheplayertobeabletomovetheframesaround
the screen.
Setting Name and Status Bars
If you were to load the addon at this point, the frames wouldn’t display
anything; however, to update the name and health/power bars the frame
needs to know when the unit it’s supposed to be displaying has changed.
When the group header reconfigures the frames, it hides each frame and
then re-shows them. You can use this to update the frame by defining an
OnShow script.
Open SquareUnitFrames.lua and add the following function:
function SquareUnitFrames_Frame_OnShow(button)
local unit = button:GetAttribute(“unit“)
if unit then
local guid = UnitGUID(unit)
if guid ~= button.guid then
SquareUnitFrames_ResetUnitButton(button.unit, unit)
button.guid = guid
end
end
end
-- Actually show the header frame
SquareUnitFrames_Header:Show()
In its current state, the group header has a tendency to show and hide the
frames more often than is strictly necessary. Knowing this, you implement
a small check to ensure you only reset the frame when the underlying unit
actually changes. First you check to make sure that the frame actually has the
unit attribute set, and then retrieve the GUID for that unit. You may recall
from Chapter 21 that the GUID is a globally unique identifier for each unit so
you can use this to track these changes.
You call an external function to actually update the button, and the reason
for this will become apparent later in the chapter. Suffice it to say that the
reset code is called from multiple places, so abstracting the code into a
function enables you to avoid maintaining it in two different places. Define
the following function after SquareUnitFrames_Frame_OnShow and before the
call that actually shows the header frame:
function SquareUnitFrames_ResetUnitButton(button, unit)
SquareUnitFrames_ResetHealthBar(button, unit)
SquareUnitFrames_ResetPowerBar(button, unit)
510 Part III Advanced Addon Techniques
SquareUnitFrames_ResetName(button, unit)
end
This function takes two arguments: the unit button sub-frame and the unit
that is being displayed by the frame. It in turn calls three more functions,
for the same reason. These implementations are extremely straightforward, so
add them now:
function SquareUnitFrames_ResetName(button, unit)
local name = UnitName(unit) or UNKNOWN
button.name:SetText(name)
end
function SquareUnitFrames_ResetHealthBar(button, unit)
local classColor = RAID_CLASS_COLORS[class]
local class = select(2, UnitClass(unit)) or “WARRIOR“
button.healthBar:SetStatusBarColor(classColor.r, i
classColor.g, classColor.b)
button.healthBar:SetMinMaxValues(0, UnitHealthMax(unit))
button.healthBar:SetValue(UnitHealth(unit))
end
function SquareUnitFrames_ResetPowerBar(button, unit)
local powerType, powerToken = UnitPowerType(unit)
local powerColor = PowerBarColor[powerToken]
button.powerBar:SetStatusBarColor(powerColor.r, i
powerColor.g, powerColor.b)
button.powerBar:SetMinMaxValues(0, UnitPowerMax(unit))
button.powerBar:SetValue(UnitPower(unit))
end
In certain cases a unit’s name might not be available, so you supply a default
of Unknown just so your unit frame displays something reasonable in those
cases. You use the global RAID_CLASS_COLORS table to look up the correct color
for the unit, and PowerBarColors to find the correct color for the power bar.
Figure 26-1 shows the resulting unit frame, if you load the addon in-game.
Figure 26-1: SquareUnitFrames showing a frame for the player
A frame is created for your character and anyone else in your party or raid,
but the name doesn’t appear to have been set. In fact, this is just a layering
issue with the textures for the status bars. Even though the font string for
Chapter 26 Creating Unit Frames with Group Templates 511
the unit’s name is on the OVERLAY layer, before graphical layers are checked,
frame levels are used to layer the graphics. Because both of the status bars are
children of the unit frame, they are at least one frame level higher than the
button, causing the textures for the status bars to appear above the font string.
There is no good way to fix this, but one way is to manually lower the frame
level of the status bars to match the main button. This may not work in all
cases, but in these simple unit frames it works quite well.
Nudging Frame Levels
Because the status bar frame levels only need to be adjusted when the frame is
first created, this is a great place to utilize initialConfigFunction.Atthetop
of SquareUnitFrames.lua, add the following function definition:
function SquareUnitFrames_InitialConfig(frame)
-- Nudge the status bar frame levels down
frame.unit.healthBar:SetFrameLevel(frame.unit:GetFrameLevel())
frame.unit.powerBar:SetFrameLevel(frame.unit:GetFrameLevel())
end
Then, right before the line that calls SquareUnitFrames_Header:Show():
SquareUnitFrames_Header.initialConfigFunction = i
SquareUnitFrames_InitialConfig
Now whenever a frame is created, the initial configuration function is called
and the frame levels are nudged so the frame displays correctly. Figure 26-2
shows SquareUnitFrames at this stage, with the names and colored status bars
visible.
Figure 26-2: SquareUnitFrames showing the player frame, after nudging frame levels.
Responding to Events and Clicks
The names are a bit squished and the frames don’t actually update when the
player’s health or power change, but if you have people leave and join your
party you should see the frames reconfiguring during combat. This section
makes the frames a bit more responsive by responding to events.
Targeting the Unit on Left-Click
Currently when you click the unit frames, they do nothing other than eat the
mouse click. As you learned in Chapter 15, you can fix this by setting attributes
512 Part III Advanced Addon Techniques
on the secure frame. Add the following to the XML definition for the unit
button, inside the main template. The code goes between the </Frames> tag
and the </Button> tag:
<Attributes>
<Attribute name=“useparent-unit“ type=“boolean“ value=“true“/>
<Attribute name=“*type1“ type=“string“ value=“target“/>
</Attributes>
The first attribute directs the frame to use the unit attribute from its parent.
Remember that the unit button isn’t the one being created by the group header,
so the attribute won’t be set on it. Inheriting the parent’s attribute in this way
ensures that any changes during combat work correctly. The second attribute
tells the frame to set all left-clicks to target the unit. In addition to this, you
could actually bind spells, macros, and other types of actions supported by the
SecureUnitButton template.
Moving the Header
As fun as creating unit frames is, having them stuck in the middle of your
screen can seriously impact your playing! You’ve done this a few times already
in this book, so add the following scripts to the unit button’s definition inside
the template (after the </Frames> tag and before the <Attributes> element):
<Scripts>
<OnDragStart function=“SquareUnitFrames_Button_OnDragStart“/>
<OnDragStop function=“SquareUnitFrames_Button_OnDragStop“/>
<OnHide function=“SquareUnitFrames_Button_OnDragStop“/>
</Scripts>
And add the corresponding functions to SquareUnitFrames.lua anywhere
before the last three lines that show the header:
function SquareUnitFrames_Button_OnDragStart(self, button)
SquareUnitFrames_Header:StartMoving()
SquareUnitFrames_Header.isMoving = true
end
function SquareUnitFrames_Button_OnDragStop(self, button)
if SquareUnitFrames_Header.isMoving then
SquareUnitFrames_Header:StopMovingOrSizing()
end
end
Note that these functions call StartMoving() and StopMovingOrSizing()
on the header, rather than on the frame itself. This ensures that the entire set
of unit frames moves together. Now add the final line to your initialization
Chapter 26 Creating Unit Frames with Group Templates 513
function SquareUnitFrames_InitialConfig, to register the button for drag
events:
button.unit:RegisterForDrag(“LeftButton“)
Reload your user interface and you should be able to drag the frames
around the screen, and click them to target the unit. If you are in the middle
of dragging the frame when someone joins or leaves the party, the header will
stop moving. This is because when the button you are dragging (the actual
unit frame you click) is hidden, the game client will not fire an OnMouseUp
event. If the OnHide script wasn’t set that way, the header would get stuck to
your mouse.
Health Update Events
Unit frames aren’t very useful without an accurate depiction of the unit’s
health, so you should register for three events, by adding the following code
to the bottom of your initial configuration function:
frame:RegisterEvent(“UNIT_HEALTH“)
frame:RegisterEvent(“UNIT_MAXHEALTH“)
frame:RegisterEvent(“PLAYER_ENTERING_WORLD“)
The first two events you should already be familiar with from your work
earlier in this book, but PLAYER_ENTERING_WORLD is a bit peculiar. Without it,
your unit frames would work in most situations, but in specific circumstances
(such as when the player releases in Tempest Keep and is resurrected outside)
the unit frames could get ‘‘stuck’’ on the wrong health display until another
event occurred. To prevent this, all unit frames will reset themselves whenever
this event occurs.
Add the OnEvent script to the definition of SquareUnitFrames_UnitTemplate,
not the sub-button you’ve been working on previously, putting the following
directly after the OnShow definition:
<OnEvent function=“SquareUnitFrames_Frame_OnEvent“/>
Create the corresponding handler by defining a new function:
function SquareUnitFrames_Frame_OnEvent(self, event, arg1, ...)
local unit = self:GetAttribute(“unit“)
if not unit then
return
end
-- Handle any events that don’t accept a unit argument
if event == “PLAYER_ENTERING_WORLD“ then
SquareUnitFrames_ResetUnitButton(self.unit, unit)
elseif arg1 and UnitIsUnit(unit, arg1) then
514 Part III Advanced Addon Techniques
if event == “UNIT_MAXHEALTH“ then
self.unit.healthBar:SetMinMaxValues(0, UnitHealthMax(unit))
self.unit.healthBar:SetValue(UnitHealth(unit))
elseif event == “UNIT_HEALTH“ then
self.unit.healthBar:SetValue(UnitHealth(unit))
end
end
end
This function first checks to ensure that the frame’s unit attribute is set;
otherwise the frame is not displaying a unit. Then the handler responds to the
PLAYER_ENTERING_WORLD event, because it doesn’t matter which unit is being
shown by the frame. Then you check that the unit being altered (passed in
arg1) is the same as the unit the frame is displaying. Inside this condition, the
unit health and maximum health events are handled, just changing the status
bars as appropriate.
Power Update Events
Properly displaying and updating the power bar for a unit frame is inherently
much more difficult, because a unit can have multiple types of power. Mana,
Energy, Rage, Runic Power, and Focus can all be queried by the UnitPower()
API function, but they all fire different types of events. Those sneaky Druids
who are able to switch between Rage, Energy, and Mana when they shapeshift
further complicate the issue.
Rather than registering for all of the events and then having to check that
you’re responding to the correct one, you’ll only register each frame for the
events that are actually relevant. Replace your existing SquareUnitFrames_
ResetPowerBar function with the following two functions (or add the first
function and just make the appropriate changes to the second):
local function unregisterManyEvents(frame, ...)
for i=1, select(“#“, ...) do
local event = select(i, ...)
frame:UnregisterEvent(event)
end
end
function SquareUnitFrames_ResetPowerBar(button, unit)
local powerType, powerToken = UnitPowerType(unit)
local powerColor = PowerBarColor[powerToken]
local alive = not UnitIsDeadOrGhost(unit)
local parent = button:GetParent()
unregisterManyEvents(parent, “UNIT_MANA“, “UNIT_RAGE“, i
“UNIT_FOCUS“,“UNIT_ENERGY“, “UNIT_RUNIC_POWER“)
unregisterManyEvents(parent, “UNIT_MAXMANA“, “UNIT_MAXRAGE“, i
“UNIT_MAXFOCUS“, “UNIT_MAXENERGY“, “UNIT_MAXRUNIC_POWER“)
Chapter 26 Creating Unit Frames with Group Templates 515
parent:RegisterEvent(“UNIT_“ .. powerToken)
parent:RegisterEvent(“UNIT_MAX“ .. powerToken)
button.powerBar:SetStatusBarColor(powerColor.r, i
powerColor.g, powerColor.b)
button.powerBar:SetMinMaxValues(0, UnitPowerMax(unit))
button.powerBar:SetValue(UnitPower(unit))
end
The unregisterManyEvents function is a simple utility that allows you to
un-register multiple events from a frame without having to do each of them
on a separate line. In the power bar reset function, you query the client to
see what type of power the unit currently has, then look up the appropriate
color in the constant table. The powerToken is the type of power in English
uppercase (such as RAGE,MANA,orRUNIC_POWER).
The function then unregisters all of the possible events, of which there are
tenfive for normal updates and five for when the maximum value changes.
Next you use a simple trick to decide what events to register by adding the
powerToken to UNIT_ and UNIT_MAX_. This allows you to avoid having a large
if statement handling each of the five cases. Finally, the color is set and the
values on the status bar are updated.
Actually registering the events and handling them is the easy bit. Add the
following to the initial configuration function, remembering that the actual
power events will be registered when the reset power bar function is called:
frame:RegisterEvent(“UNIT_DISPLAYPOWER“)
The actual event handler can use the same trickthat you used in the preceding
code, but it needs to query the client in order to test. Add the following line
to SquareUnitFrames_Frame_OnEvent immediately after the line that begins
elseif arg1 and:
local powerType, powerToken = UnitPowerType(unit)
Then add the conditions inside the sub-conditional that ensures that the unit
attribute is set, and the unit actually exists (the same block where you handle
health and power updates):
elseif event == “UNIT_DISPLAYPOWER“ then
SquareUnitFrames_ResetPowerBar(self.unit, unit)
elseif event == “UNIT_“ .. powerToken then
self.unit.powerBar:SetValue(UnitPower(unit))
elseif event == “UNIT_MAX“ .. powerToken then
self.unit.powerBar:SetMinMaxValues(0, UnitPowerMax(unit))
self.unit.powerBar:SetValue(UnitPower(unit))
516 Part III Advanced Addon Techniques
When the unit’s display power changes you reset the entire bar to ensure
that it’s re-colored and the min/max values are correct. To test the other two
events, you just concatenate the powerToken again and update the status bars
accordingly. Now the unit frame should properly show power gain and loss,
and switch correctly when a unit’s power type changes.
Responding to Name Changes
At times either the game client is unable to resolve a name immediately, or the
name of a unit token might change. When this happens, the UNIT_NAME_UPDATE
event fires, so you can update your frames accordingly.
Add the event registration to your initial configuration function:
frame:RegisterEvent(“UNIT_NAME_UPDATE“)
Now add the event to your OnEvent function, by adding the following in
the same block as the health and power updates (because this event passes the
unit argument):
elseif event == “UNIT_NAME_UPDATE“ then
SquareUnitFrames_ResetName(self.unit, unit)
That’s the end of the compulsory portion of creating a normal unit frame.
The next section shows you how to add a number of enhancements to your
frames.
Enhancing SquareUnitFrames
This is the fun part of addon writing! Once you have something basic working,
you’re able to add features until you have the addon just right for your
purposes. Here are the features you are going to add to make this addon a bit
more useful:
Highlight units on mouseover, so it’s clear who the player is selecting
Highlight the unit that is the player’s current target
Show the unit’s threat level by coloring the unit name
Show dead players more prominently
Prevent WoW from truncating longer names with ...
Replace the mana bar with a pet frame when the unit has a pet
Highlighting Units on Mouseover
This is probably the simplest modification, because Blizzard’s system
already has so much support for it. Remember that any texture in the
Chapter 26 Creating Unit Frames with Group Templates 517
HIGHLIGHT layer is displayed when the mouse is over that texture. Simply
add the following at the bottom of the unit sub-button definition inside the
template:
<HighlightTexture file=i
“Interface\Buttons\ButtonHilight-Square“ alphaMode=“ADD“/>
Now each time you move your mouse over a unit in the grid, you’ll see a
border around the frame. Figure 26-3 shows this feature in action!
Figure 26-3: SquareUnitFrames highlighting units on mouseover
Showing the Targeted Unit
Showing the targeted unit is a bit more complex, because you need to watch
for changes to the player’s target and then update accordingly. First you
should create a texture in the unit button inside the template that can be
shown to indicate selection. Add the following in the OVERLAY layer of the unit
sub-button definition:
<Texture name=“$parent_Selected“ parentKey=“selected“ i
setAllPoints=“true“
file=“Interface\Buttons\CheckButtonHilight“ alphaMode=“ADD“ i
hidden=“true“/>
Next you need to register for the PLAYER_TARGET_CHANGED event so you can
show the texture on the selected unit and ensure the texture is hidden on all
others. Add the event registration to your initial config function:
frame:RegisterEvent(“PLAYER_TARGET_CHANGED“)
Now add the following condition to your event handler after PLAYER_
ENTERING_WORLD; there is no need to check the unit argument for this event:
elseif event == “PLAYER_TARGET_CHANGED“ then
if UnitIsUnit(unit, “target“) then
self.unit.selected:Show()
else
self.unit.selected:Hide()
end
Although this will work in most cases, you should probably add it to the
reset button function as well; otherwise if your party members were to change
518 Part III Advanced Addon Techniques
while you keep the same target, your unit frames wouldn’t properly show it.
Add this code to SquareUnitFrames_ResetUnitButton:
if UnitIsUnit(unit, “target“) then
button.selected:Show()
else
button.selected:Hide()
end
Figure 26-4 shows the difference between mouseover highlighting and the
selection texture.
Figure 26-4: SquareUnitFrames showing both the selected unit and the unit the mouse
is over.
Displaying Threat Levels
In the Wrath of the Lich King expansion, WoW introduced a threat sys-
tem that can be queried by addons. Although the functions can be queried
for specific mobs, you are only concerned with the global threat of each
unit (that is, whether or not a mob is focusing on the unit). Fortunately,
this is very easy to accomplish. Add the following code to the bottom of
SquareUnitFrames_ResetName:
local status = UnitThreatSituation(unit)
if status and status > 0 then
local r, g, b = GetThreatStatusColor(status)
button.name:SetTextColor(r, g, b)
else
button.name:SetTextColor(1, 1, 1)
end
This function queries the threat situation status for the given unit, and then
retrieves the correct color and applies it to the font string. Now register for the
event in your initial configuration function:
frame:RegisterEvent(“UNIT_THREAT_SITUATION_UPDATE“)
Finally, add the condition to the event handler as follows, in the
sub-conditional that checks the unit argument, after the UNIT_NAME_UPDATE
condition:
elseif event == “UNIT_THREAT_SITUATION_UPDATE“ then
local status = UnitThreatSituation(unit)
if status and status > 0 then
local r, g, b = GetThreatStatusColor(status)
Chapter 26 Creating Unit Frames with Group Templates 519
self.unit.name:SetTextColor(r, g, b)
else
self.unit.name:SetTextColor(1, 1, 1)
end
Figure 26-5 shows a raid group with names colored to indicate threat level.
Figure 26-5: SquareUnitFrames showing threat levels for party members
Showing Dead Players
Right now if someone in your group were to die, it would be difficult to see if
they were actually dead or just very low on health. You can fix this by changing
the status bar’s color to gray and filling it in. Change your implementation of
SquareUnitFrames_ResetHealthBar to the following:
function SquareUnitFrames_ResetHealthBar(button, unit)
local class = select(2, UnitClass(unit)) or “WARRIOR“
local classColor = RAID_CLASS_COLORS[class]
local alive = not UnitIsDeadOrGhost(unit)
if alive then
button.healthBar:SetStatusBarColor(classColor.r, i
classColor.g, classColor.b)
button.healthBar:SetMinMaxValues(0, UnitHealthMax(unit))
button.healthBar:SetValue(UnitHealth(unit))
button.dead = false
else
button.healthBar:SetStatusBarColor(0.3, 0.3, 0.3)
button.healthBar:SetMinMaxValues(0, 1)
button.healthBar:SetValue(1)
button.dead = true
end
end
The first two lines are the same, but then you use the UnitIsDeadOrGhost
function to (shockingly) check to see if the unit is either dead or a ghost. You
then either color the status bar based on the class color, or change it to grey
and fill it in. You also set a flag on the unit button that you’ll use in the event
handler to indicate whether the status bar is currently showing the player as
dead or alive.
Change the UNIT_HEALTH and UNIT_MAXHEALTH portion of the event handler
to the following:
if event == “UNIT_MAXHEALTH“ then
if self.unit.dead ~= UnitIsDeadOrGhost(unit) then
SquareUnitFrames_ResetUnitButton(self.unit, unit)
520 Part III Advanced Addon Techniques
else
self.unit.healthBar:SetMinMaxValues(0, UnitHealthMax(unit))
self.unit.healthBar:SetValue(UnitHealth(unit))
end
elseif event == “UNIT_HEALTH“ then
if self.unit.dead ~= UnitIsDeadOrGhost(unit) then
SquareUnitFrames_ResetUnitButton(self.unit, unit)
else
self.unit.healthBar:SetValue(UnitHealth(unit))
end
Here you just check to see if your flag is different from the return of
UnitIsDeadOrGhost and then adjust the frame accordingly. When a unit dies
the API still shows it as having power, so color that grey as well. Open up
SquareUnitFrames_ResetPowerBar and replace the last three lines:
button.powerBar:SetStatusBarColor(powerColor.r, powerColor.g, i
powerColor.b)
button.powerBar:SetMinMaxValues(0, UnitPowerMax(unit))
button.powerBar:SetValue(UnitPower(unit))
with the following:
local alive = not UnitIsDeadOrGhost(unit)
if alive then
button.powerBar:SetStatusBarColor(powerColor.r, i
powerColor.g, powerColor.b)
else
button.powerBar:SetStatusBarColor(0.3, 0.3, 0.3)
end
button.powerBar:SetMinMaxValues(0, UnitPowerMax(unit))
button.powerBar:SetValue(UnitPower(unit))
Change the event handler by replacing the power event conditions with the
following code:
elseif event == “UNIT_“ .. powerToken then
if self.unit.dead ~= UnitIsDeadOrGhost(unit) then
SquareUnitFrames_ResetPowerBar(self.unit, unit)
else
self.unit.powerBar:SetValue(UnitPower(unit))
end
elseif event == “UNIT_MAX“ .. powerToken then
if self.unit.dead ~= UnitIsDeadOrGhost(unit) then
SquareUnitFrames_ResetPowerBar(self.unit, unit)
else
self.unit.powerBar:SetMinMaxValues(0, UnitPowerMax(unit))
self.unit.powerBar:SetValue(UnitPower(unit))
end
Chapter 26 Creating Unit Frames with Group Templates 521
Figure 26-6 shows the unit frames with a dead unit, which is much easier to
see when it’s shaded.
Figure 26-6: SquareUnitFrames showing a dead unit shaded out
Displaying Unit Names
Currently, whenever SquareUnitFrames displays a name that is longer than
four characters (and some names that are shorter), it is truncated with an
ellipsis (‘‘ ... ’’) at the end. This isn’t very desirablean ellipsis takes up
much of the unit button’s width, space that could be better used to display
more characters of the namebut WoW doesn’t really provide an easy way
to fit as much of a name as possible in a font string of limited width.
What you can do instead is try different substrings of the name in order to
fit as many characters as you can in a 30-pixel-wide font string. This algorithm
might look like this:
local substring(name, length)
for length=#name, 1, -1 do
substring = string.sub(name, 1, length)
button.name:SetText(substring)
if button.name:GetStringWidth() <= 30 then
button.shortname = substring
return
end
end
First you take the entire string and set a font string to display it. Then you
check to see what the width of the resulting display is. You continue to take
one less character and as soon as you have something that is less than or equal
to 30 pixels in width, you accept it and store it in the button (so you can re-use
it later instead of re-calculating it).
This process, however, will have a big problem with names that contain
non-alphanumeric characters, such as letters with accents and other spe-
cial symbols. These characters are encoded using a standard called UTF-8.
Although UTF-8 is very far outside the scope of this book, you can read more
information about it at http://en.wikipedia.org/wiki/Utf8. What you need
to know is that although each of those special characters can be represented by
multiple bytes, Lua’s string library treats each byte as an individual character.
The following is sample output from World of Warcraft:
> print(string.len(“Gr¨
uber“))
7
522 Part III Advanced Addon Techniques
Even though Gr ¨
uber has only six visible characters, it’s actually made up
of seven different characters from the Lua string library’s point of view. If
you tried to examine the substring between character positions 1 and 3 you
would only get half of the ‘‘ ¨
u’’ character. That’s because Lua’s built-in string
processing functions aren’t UTF-8 aware.
Luckily we’ve done the work so you don’t have to, and have created
a function that takes in a string, a start index, and a number of char-
acters to retrieve. Define this function directly above your definition of
SquareUnitFrames_ResetName (you can include the comments if you’d like):
-- This function can return a substring of a UTF-8 string, properly
-- handling UTF-8 codepoints. Rather than taking a start index and
-- optionally an end index, it takes the string, the start index, and
-- the number of characters to select from the string.
--
-- UTF-8 Reference:
-- 0xxxxxx - ASCII character
-- 110yyyxx - 2 byte UTF codepoint
-- 1110yyyy - 3 byte UTF codepoint
-- 11110zzz - 4 byte UTF codepoint
local function utf8sub(str, start, numChars)
local currentIndex = start
while numChars > 0 and currentIndex <= #str do
local char = string.byte(str, currentIndex)
if char >= 240 then
currentIndex = currentIndex + 4
elseif char >= 225 then
currentIndex = currentIndex + 3
elseif char >= 192 then
currentIndex = currentIndex + 2
else
currentIndex = currentIndex + 1
end
numChars = numChars - 1
end
return str:sub(start, currentIndex - 1)
end
Next, change the definition of SquareUnitFrames_ResetName to the
following:
function SquareUnitFrames_ResetName(button, unit)
local name = UnitName(unit) or “Unknown“
local substring
for length=#name, 1, -1 do
substring = utf8sub(name, 1, length)
button.name:SetText(substring)
Chapter 26 Creating Unit Frames with Group Templates 523
if button.name:GetStringWidth() <= 30 then
return
end
end
local status = UnitThreatSituation(unit)
if status and status > 0 then
local r, g, b = GetThreatStatusColor(status)
button.name:SetTextColor(r, g, b)
else
button.name:SetTextColor(1, 1, 1)
end
end
Sure, it’s a lot of code to accomplish something that should be relatively
easy, but it makes the frames look so much neater. Figure 26-7 shows the
difference between the old version and the new improved version.
Figure 26-7: SquareUnitFrames showing truncated names, and the version using the
fitting algorithm
Adding Pets to SquareUnitFrames
The state handlers system makes it extremely easy to add a pet frame that is
shown/hidden correctly, even when the player is in combat. The first thing
you need to do is create the frame definition in the XML file. Add the following
after the </Button> tag for the unit sub-button, but before the </Frames> tag
for the XML template:
<Button name=“$parent_Pet“ parentKey=“pet“
inherits=“SecureHandlerShowHideTemplate,SecureUnitButtonTemplate“>
<Size x=“34“ y=“5“/>
<Anchors>
<Anchor point=“BOTTOMLEFT“>
<Offset x=“1“ y=“1“/>
</Anchor>
</Anchors>
<Frames>
<StatusBar name=“$parent_HealthBar“ parentKey=“healthBar“
setAllPoints=“true“>
<BarTexture file=“Interface\Buttons\UI-Listbox-Highlight2“/>
524 Part III Advanced Addon Techniques
<BarColor r=“0.0“ g=“1.0“ b=“0.0“/>
</StatusBar>
</Frames>
<Attributes>
<Attribute name=“useparent-unit“ type=“boolean“ value=“true“/>
<Attribute name=“unitsuffix“ type=“string“ value=“pet“/>
<Attribute name=“*type1“ type=“string“ value=“target“/>
</Attributes>
<HighlightTexture file=“Interface\Buttons\UI-Listbox-Highlight2“
alphaMode=“ADD“/>
</Button>
This definition inherits from SecureHandlerShowHideTemplate as well as
SecureUnitButtonTemplate. This enables you to run code when the frame
is shown or hidden, and allows you to enable left-click to target the unit.
The frame is hidden by default, and you’ll register it to be shown whenever
the unit has a pet. The unitsuffix attribute here, when combined with
useparent-unit, ensures that the frame inherits the unit attribute from its
parent, and adds pet to the end, giving you the pet’s unit identifier.
Add the following code to the end of SquareUnitFrames_InitialConfig:
RegisterUnitWatch(frame.pet)
frame.pet:SetFrameRef(“unit“, frame.unit)
frame.pet:SetAttribute(“_onshow“, [[
local unit = self:GetFrameRef(“unit“)
unit:SetHeight(28)
]])
frame.pet:SetAttribute(“_onhide“, [[
local unit = self:GetFrameRef(“unit“)
unit:SetHeight(34)
]])
frame.pet.unit = frame.unit
frame.pet:HookScript(“OnShow“, SquareUnitFrames_Pet_OnShow)
frame.pet:HookScript(“OnHide“, SquareUnitFrames_Pet_OnHide)
Thefirstlinesimplyregistersthepetframetobeshown/hiddenbasedon
the existence of the unit it’s set to display. Next two secure snippets are created
that will be run when the frame is shown and hidden. The first changes the
height of the unit frame to be 6 pixels smaller, and the second changes it back
to the original height.
Next, you set button.pet.unit to be equal to button.unit. This allows
you to easily access the unit button from within the pet button’s handlers.
Finally, you hook the OnShow and OnHide widget scripts so you can run some
non-secure code. This is because non-secure frames cannot be altered from
secure snippets, and vice versa. You want to hide the power bar (which is not
secure), so this is the best way to accomplish this.
Chapter 26 Creating Unit Frames with Group Templates 525
Define these two functions somewhere in your Lua file before the header
show at the end:
function SquareUnitFrames_Pet_OnShow(self)
self.unit.healthBar:SetHeight(28)
self.unit.powerBar:Hide()
end
function SquareUnitFrames_Pet_OnHide(self)
self.unit.healthBar:SetHeight(30)
self.unit.powerBar:Show()
end
The height of the health bar is changed and the power bar is shown or
hidden. What all of this will accomplish is making the unit frame a bit smaller,
and removing the power bar. Then the pet health bar is placed below the unit
frames (but big enough that it can still be easily seen and clicked).
Add a function that resets the pet button when requested, so it can be used
elsewhere in the code:
function SquareUnitFrames_ResetPetButton(button, unit)
if UnitExists(unit) then
local health = UnitHealth(unit)
local maxHealth = UnitHealth(unit)
button.healthBar:SetMinMaxValues(0, maxHealth)
button.healthBar:SetValue(health)
end
end
Add a call to this function in the SquareUnitFrames_Frame_OnShow function,
right after the call to SquareUnitFrames_ResetUnitButton (note that you
append pet to the end of the unit token so it looks at the correct unit):
SquareUnitFrames_ResetPetButton(button.pet, unit .. “pet“)
Finally, add event handlers for the unit’s health by adding the following to
the OnEvent script. This code should be added in the outermost else statement,
after the first UnitIsUnit block (if you’re confused, you can always skip to the
end of the chapter and see where it lies in the context of the whole function):
elseif arg1 and UnitIsUnit(unit .. “pet“, arg1) then
if event == “UNIT_MAXHEALTH“ then
self.pet.healthBar:SetMinMaxValues(0, UnitHealthMax(arg1))
self.pet.healthBar:SetValue(UnitHealth(arg1))
elseif event == “UNIT_HEALTH“ then
self.pet.healthBar:SetValue(UnitHealth(arg1))
end
end
526 Part III Advanced Addon Techniques
It’s a relatively small amount of code to write for such a big change to
functionality. Figure 26-8 shows a warlock without a pet and with an imp
summoned and fighting.
Figure 26-8: SquareUnitFrames for a warlock without a pet (left) and with a summoned
pet (right).
Creating a SecureGroupPetHeaderTemplate
If instead of adding pets to an existing frame, you just want to have a header
consisting solely of pets, Blizzard has provided a template just for this purpose.
In addition to the attributes allowed by the SecureGroupHeaderTemplate,the
following two attributes can be used to customize the display of party/
raid pets:
useOwnerUnit (boolean)When true,theunit attribute on the created
frames corresponds to the owner’s unit instead of the pet’s unit.
filterOnPet (boolean)When true, the pet’s names are used when
sorting and filtering.
In addition to these specific attributes, the pet header accepts the same
attributes as the normal secure group header.
Summary
Although stringent limitations exist as to what can be accomplished in an
addon, a number of powerful templates allow developers to make extremely
functional addons. This chapter introduced you to the group header templates,
and created an extensive party/raid addon.
The Code
SquareUnitFrames
SquareUnitFrames.toc
## Interface: 30300
## Title: SquareUnitFrames
## Notes: Square shaped party/raid frames
SquareUnitFrames.xml
SquareUnitFrames.lua
Chapter 26 Creating Unit Frames with Group Templates 527
SquareUnitFrames.xml
<Ui
xmlns=“http://www.blizzard.com/wow/ui/“
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance“
xsi:schemaLocation=“http://www.blizzard.com/wow/ui/
http://wowprogramming.com/FrameXML/UI.xsd“>
<Frame name=“SquareUnitFrames_UnitTemplate“ virtual=“true“>
<Size x=“36“ y=“36“/>
<Layers>
<Layer level=“BACKGROUND“>
<Texture setAllPoints=“true“>
<Color r=“0.0“ g=“0.0“ b=“0.0“/>
</Texture>
</Layer>
</Layers>
<Frames>
<Button name=“$parent_Unit“ parentKey=“unit“
inherits=“SecureUnitButtonTemplate“>
<Size x=“34“ y=“34“/>
<Anchors>
<Anchor point=“TOPLEFT“>
<Offset x=“1“ y=“-1“/>
</Anchor>
</Anchors>
<Layers>
<Layer level=“OVERLAY“>
<FontString name=“$parent_Name“ parentKey=“name“
inherits=“GameFontHighlight“ setAllPoints=“true“/>
<Texture name=“$parent_Selected“ parentKey=“selected“
setAllPoints=“true“
file=“Interface\Buttons\CheckButtonHilight“
alphaMode=“ADD“ hidden=“true“/>
</Layer>
</Layers>
<Frames>
<StatusBar name=“$parent_HealthBar“
parentKey=“healthBar“>
<Size x=“34“ y=“30“/>
<Anchors>
<Anchor point=“TOPLEFT“/>
</Anchors>
<BarTexture
file=“Interface\Buttons\UI-Listbox-Highlight2“/>
<BarColor r=“1.0“ g=“1.0“ b=“1.0“/>
</StatusBar>
<StatusBar name=“$parent_PowerBar“ parentKey=“powerBar“>
<Size x=“34“ y=“3“/>
<Anchors>
<Anchor point=“TOPLEFT“
528 Part III Advanced Addon Techniques
relativeTo=“$parent_HealthBar“
relativePoint=“BOTTOMLEFT“>
<Offset x=“0“ y=“-1“/>
</Anchor>
</Anchors>
<BarTexture
file=“Interface\TargetingFrame\UI-TargetingFrame-i
BarFill“/>
<BarColor r=“1.0“ g=“1.0“ b=“1.0“/>
</StatusBar>
</Frames>
<Scripts>
<OnDragStart
function=“SquareUnitFrames_Button_OnDragStart/>
<OnDragStop
function=“SquareUnitFrames_Button_OnDragStop“/>
<OnHide function=“SquareUnitFrames_Button_OnDragStop“/>
</Scripts>
<Attributes>
<Attribute name=“useparent-unit“ type=“boolean“
value=“true“/>
<Attribute name=“*type1“ type=“string“ value=“target“/>
</Attributes>
<HighlightTexture
file=“Interface\Buttons\ButtonHilight-Square“
alphaMode=“ADD“/>
</Button>
<Button name=“$parent_Pet“ parentKey=“pet“
inherits=“SecureHandlerShowHideTemplate,i
SecureUnitButtonTemplate“>
<Size x=“34“ y=“5“/>
<Anchors>
<Anchor point=“BOTTOMLEFT“>
<Offset x=“1“ y=“1“/>
</Anchor>
</Anchors>
<Frames>
<StatusBar name=“$parent_HealthBar“ parentKey=“healthBar“
setAllPoints=“true“>
<BarTexture
file=“Interface\Buttons\UI-Listbox-Highlight2“/>
<BarColor r=“0.0“ g=“1.0“ b=“0.0“/>
</StatusBar>
</Frames>
<Attributes>
<Attribute name=“useparent-unit“ type=“boolean“
value=“true“/>
<Attribute name=“unitsuffix“ type=“string“ value=“pet“/>
<Attribute name=“*type1“ type=“string“ value=“target“/>
</Attributes>
Chapter 26 Creating Unit Frames with Group Templates 529
<HighlightTexture
file=“Interface\Buttons\UI-Listbox-Highlight2“
alphaMode=“ADD“/>
</Button>
</Frames>
<Scripts>
<OnShow function=“SquareUnitFrames_Frame_OnShow“/>
<OnEvent function=“SquareUnitFrames_Frame_OnEvent“/>
</Scripts>
</Frame>
<Frame name=“SquareUnitFrames_Header“ parent=“UIParent“
inherits=“SecureGroupHeaderTemplate“ movable=“true“>
<Anchors>
<Anchor point=“CENTER“/>
</Anchors>
<Attributes>
<Attribute name=“showParty“ type=“boolean“ value=“true“/>
<Attribute name=“showRaid“ type=“boolean“ value=“true“/>
<Attribute name=“showPlayer“ type=“boolean“ value=“true“/>
<Attribute name=“showSolo“ type=“boolean“ value=“true“/>
<Attribute name=“maxColumns“ type=“number“ value=“8“/>
<Attribute name=“unitsPerColumn“ type=“number“ value=“5“/>
<Attribute name=“columnAnchorPoint“ type=“string“
value=“TOP“/>
<Attribute name=“point“ type=“string“ value=“LEFT“/>
<Attribute name=“template“ type=“string“
value=“SquareUnitFrames_UnitTemplate“/>
<Attribute name=“templateType“ type=“string“ value=“Frame“/>
<Attribute name=“xOffset“ type=“number“ value=“-1“/>
<Attribute name=“yOffset“ type=“number“ value=“1“/>
</Attributes>
</Frame>
</Ui>
SquareUnitFrames.lua
function SquareUnitFrames_InitialConfig(frame)
-- Nudge the status bar frame levels down
frame.unit.healthBar:SetFrameLevel(frame.unit:GetFrameLevel())
frame.unit.powerBar:SetFrameLevel(frame.unit:GetFrameLevel())
frame.unit:RegisterForDrag(“LeftButton“)
frame:RegisterEvent(“UNIT_HEALTH“)
frame:RegisterEvent(“UNIT_MAXHEALTH“)
frame:RegisterEvent(“PLAYER_ENTERING_WORLD“)
frame:RegisterEvent(“UNIT_DISPLAYPOWER“)
frame:RegisterEvent(“UNIT_NAME_UPDATE“)
frame:RegisterEvent(“PLAYER_TARGET_CHANGED“)
frame:RegisterEvent(“UNIT_THREAT_SITUATION_UPDATE“)
530 Part III Advanced Addon Techniques
RegisterUnitWatch(frame.pet)
frame.pet:SetFrameRef(“unit“, frame.unit)
frame.pet:SetAttribute(“_onshow“, [[
local unit = self:GetFrameRef(“unit“)
unit:SetHeight(28)
]])
frame.pet:SetAttribute(“_onhide“, [[
local unit = self:GetFrameRef(“unit“)
unit:SetHeight(34)
]])
frame.pet.unit = frame.unit
frame.pet:HookScript(“OnShow“, SquareUnitFrames_Pet_OnShow)
frame.pet:HookScript(“OnHide“, SquareUnitFrames_Pet_OnHide)
end
function SquareUnitFrames_Frame_OnShow(button)
local unit = button:GetAttribute(“unit“)
if unit then
local guid = UnitGUID(unit)
if guid ~= button.guid then
SquareUnitFrames_ResetUnitButton(button.unit, unit)
SquareUnitFrames_ResetPetButton(button.pet, unit .. “pet“)
button.guid = guid
end
end
end
function SquareUnitFrames_ResetUnitButton(button, unit)
SquareUnitFrames_ResetHealthBar(button, unit)
SquareUnitFrames_ResetPowerBar(button, unit)
SquareUnitFrames_ResetName(button, unit)
if UnitIsUnit(unit, “target“) then
button.selected:Show()
else
button.selected:Hide()
end
local status = UnitThreatSituation(unit)
if status and status > 0 then
local r, g, b = GetThreatStatusColor(status)
button.name:SetTextColor(r, g, b)
else
button.name:SetTextColor(1, 1, 1)
end
end
Chapter 26 Creating Unit Frames with Group Templates 531
-- This function can return a substring of a UTF-8 string,
-- properly handling UTF-8 codepoints. Rather than taking a start
-- index and optionally an end index, it takes the string, the
-- start index and the number of characters to select from the
-- string.
--
-- UTF-8 Reference:
-- 0xxxxxx - ASCII character
-- 110yyyxx - 2 byte UTF codepoint
-- 1110yyyy - 3 byte UTF codepoint
-- 11110zzz - 4 byte UTF codepoint
local function utf8sub(str, start, numChars)
local currentIndex = start
while numChars > 0 and currentIndex <= #str do
local char = string.byte(str, currentIndex)
if char >= 240 then
currentIndex = currentIndex + 4
elseif char >= 225 then
currentIndex = currentIndex + 3
elseif char >= 192 then
currentIndex = currentIndex + 2
else
currentIndex = currentIndex + 1
end
numChars = numChars - 1
end
return str:sub(start, currentIndex - 1)
end
function SquareUnitFrames_ResetName(button, unit)
local name = UnitName(unit) or “Unknown“
local substring
for length=#name, 1, -1 do
substring = utf8sub(name, 1, length)
button.name:SetText(substring)
if button.name:GetStringWidth() <= 30 then
return
end
end
local status = UnitThreatSituation(unit)
if status and status > 0 then
local r, g, b = GetThreatStatusColor(status)
button.name:SetTextColor(r, g, b)
else
button.name:SetTextColor(1, 1, 1)
end
end
532 Part III Advanced Addon Techniques
function SquareUnitFrames_ResetHealthBar(button, unit)
local class = select(2, UnitClass(unit)) or “WARRIOR“
local classColor = RAID_CLASS_COLORS[class]
local alive = not UnitIsDeadOrGhost(unit)
if alive then
button.healthBar:SetStatusBarColor(classColor.r, i
classColor.g, classColor.b)
button.healthBar:SetMinMaxValues(0, UnitHealthMax(unit))
button.healthBar:SetValue(UnitHealth(unit))
button.dead = false
else
button.healthBar:SetStatusBarColor(0.3, 0.3, 0.3)
button.healthBar:SetMinMaxValues(0, 1)
button.healthBar:SetValue(1)
button.dead = true
end
end
function SquareUnitFrames_ResetPowerBar(button, unit)
local powerType, powerToken = UnitPowerType(unit)
local powerColor = PowerBarColor[powerToken]
local alive = not UnitIsDeadOrGhost(unit)
if alive then
button.powerBar:SetStatusBarColor(powerColor.r, i
powerColor.g, powerColor.b)
else
button.powerBar:SetStatusBarColor(0.3, 0.3, 0.3)
end
button.powerBar:SetMinMaxValues(0, UnitPowerMax(unit))
button.powerBar:SetValue(UnitPower(unit))
end
function SquareUnitFrames_Button_OnDragStart(self, button)
SquareUnitFrames_Header:StartMoving()
SquareUnitFrames_Header.isMoving = true
end
function SquareUnitFrames_Button_OnDragStop(self, button)
if SquareUnitFrames_Header.isMoving then
SquareUnitFrames_Header:StopMovingOrSizing()
end
end
function SquareUnitFrames_Frame_OnEvent(self, event, arg1, ...)
local unit = self:GetAttribute(“unit“)
if not unit then
return
Chapter 26 Creating Unit Frames with Group Templates 533
end
-- Handle any events that don’t accept a unit argument
if event == “PLAYER_ENTERING_WORLD“ then
SquareUnitFrames_ResetUnitButton(self.unit, unit)
elseif event == “PLAYER_TARGET_CHANGED“ then
if UnitIsUnit(unit, “target“) then
self.unit.selected:Show()
else
self.unit.selected:Hide()
end
elseif arg1 and UnitIsUnit(unit, arg1) then
local powerType, powerToken = UnitPowerType(unit)
if event == “UNIT_MAXHEALTH“ then
if self.unit.dead ~= UnitIsDeadOrGhost(unit) then
SquareUnitFrames_ResetUnitButton(self.unit, unit)
else
self.unit.healthBar:SetMinMaxValues(0, UnitHealthMax(unit))
self.unit.healthBar:SetValue(UnitHealth(unit))
end
elseif event == “UNIT_HEALTH“ then
if self.unit.dead ~= UnitIsDeadOrGhost(unit) then
SquareUnitFrames_ResetUnitButton(self.unit, unit)
else
self.unit.healthBar:SetValue(UnitHealth(unit))
end
elseif event == “UNIT_DISPLAYPOWER“ then
SquareUnitFrames_ResetPowerBar(self.unit, unit)
elseif event == “UNIT_“ .. powerToken then
if self.unit.dead ~= UnitIsDeadOrGhost(unit) then
SquareUnitFrames_ResetPowerBar(self.unit, unit)
else
self.unit.powerBar:SetValue(UnitPower(unit))
end
elseif event == “UNIT_MAX“ .. powerToken then
if self.unit.dead ~= UnitIsDeadOrGhost(unit) then
SquareUnitFrames_ResetPowerBar(self.unit, unit)
else
self.unit.powerBar:SetMinMaxValues(0, UnitPowerMax(unit))
self.unit.powerBar:SetValue(UnitPower(unit))
end
elseif event == “UNIT_NAME_UPDATE“ then
SquareUnitFrames_ResetName(self.unit, unit)
elseif event == “UNIT_THREAT_SITUATION_UPDATE“ then
local status = UnitThreatSituation(unit)
if status and status > 0 then
local r, g, b = GetThreatStatusColor(status)
self.unit.name:SetTextColor(r, g, b)
else
self.unit.name:SetTextColor(1, 1, 1)
534 Part III Advanced Addon Techniques
end
end
elseif arg1 and UnitIsUnit(unit .. “pet“, arg1) then
if event == “UNIT_MAXHEALTH“ then
self.pet.healthBar:SetMinMaxValues(0, UnitHealthMax(arg1))
self.pet.healthBar:SetValue(UnitHealth(arg1))
elseif event == “UNIT_HEALTH“ then
self.pet.healthBar:SetValue(UnitHealth(arg1))
end
end
end
local function unregisterManyEvents(frame, ...)
for i=1, select(“#“, ...) do
local event = select(i, ...)
frame:UnregisterEvent(event)
end
end
function SquareUnitFrames_ResetPowerBar(button, unit)
local powerType, powerToken = UnitPowerType(unit)
local powerColor = PowerBarColor[powerToken]
local alive = not UnitIsDeadOrGhost(unit)
local parent = button:GetParent()
unregisterManyEvents(parent, “UNIT_MANA“, “UNIT_RAGE“,
“UNIT_FOCUS“,“UNIT_ENERGY“, “UNIT_RUNIC_POWER“)
unregisterManyEvents(parent, “UNIT_MAXMANA“, “UNIT_MAXRAGE“,
“UNIT_MAXFOCUS“, “UNIT_MAXENERGY“, “UNIT_MAXRUNIC_POWER“)
parent:RegisterEvent(“UNIT_“ .. powerToken)
parent:RegisterEvent(“UNIT_MAX“ .. powerToken)
button.powerBar:SetStatusBarColor(powerColor.r, i
powerColor.g, powerColor.b)
button.powerBar:SetMinMaxValues(0, UnitPowerMax(unit))
button.powerBar:SetValue(UnitPower(unit))
end
function SquareUnitFrames_Pet_OnShow(self)
self.unit.healthBar:SetHeight(28)
self.unit.powerBar:Hide()
end
function SquareUnitFrames_Pet_OnHide(self)
self.unit.healthBar:SetHeight(30)
self.unit.powerBar:Show()
end
function SquareUnitFrames_ResetPetButton(button, unit)
Chapter 26 Creating Unit Frames with Group Templates 535
if UnitExists(unit) then
local health = UnitHealth(unit)
local maxHealth = UnitHealth(unit)
button.healthBar:SetMinMaxValues(0, maxHealth)
button.healthBar:SetValue(health)
end
end
-- Actually show the header frame
SquareUnitFrames_Header.initialConfigFunction = i
SquareUnitFrames_InitialConfig
SquareUnitFrames_Header:Show()
Part
IV
Reference
In This Part
Chapter 27: API Reference
Chapter 28: API Categories
Chapter 29: Widget Reference
Chapter 30: Events Reference
CHAPTER
27
API Reference
The World of Warcraft API contains more than a thousand functions that can be used
to interact with the game client, and obtain information about the state of the game.
This chapter includes an alphabetic listing of each of these functions with detailed
descriptions of what each function does, what arguments it takes, and what values it
returns to the caller.
Although all efforts were made to provide the most up-to-date listing of func-
tions, the API is a constantly moving target, changing from patch to patch. For
the most current listing of the API please visit the book’s companion website
at http://wowprogramming.com/docs. Information about upcoming changes to
the API can be found on the official World of Warcraft UI & Macros Forums:
http://forums.worldofwarcraft.com/board.html?forumId=11114.
API Reference Conventions
Following each function is a description of what the function does, along with
the function signature, followed by any arguments, returns, or example snippets
of code.
Function Signatures
A function signature is a short way to express the name of a function, the argu-
ments that the function expects to be called with, and any values that the function
may return. Consider the following signature for the CalculateAuctionDeposit()
function:
deposit = CalculateAuctionDeposit(runTime)
539
540 Part IV Reference
This notation indicates that the function accepts a single argument called runTime,
and returns a single value called deposit. These aren’t requirements for names: they
are simply names given to each of the arguments and returns, to make the signature
easier to read and understand.
If a function signature is omitted, then the function takes no arguments, and returns
no values. This is equivalent to the function signature FunctionName(),sothese
signatures are not listed.
Optional Arguments
When a signature contains an optional argument, it is wrapped in square brackets to
indicate this. Here’s the function signature for BuyMerchantItem():
BuyMerchantItem(index [,quantity])
This signature shows that the function returns no arguments and takes an argument
index, along with an optional argument quantity. The specific details of what the
optional argument does are listed in the description for that argument, which is
displayed below the signature.
Functions can have multiple nested optional arguments, like SendChatMessage():
SendChatMessage(“text“ [,“chatType“ [,“language“ [,“channel“]]])
This function requires the first argument text,butcanalsotakeuptothreemore
arguments. The optional arguments are nested in this way because to include the argu-
ment language, you must also include something for chatType (even if it’s the value
nil). Likewise, to supply a channel argument, you must also supply values for
chatType and language.
Argument Choices
Certain functions, such as IsAddOnLoaded(), have alternative choices in their argu-
ments:
loaded = IsAddOnLoaded(index) or IsAddOnLoaded(“name“)
This function can take either the index of addon in the addon listing, or the name of
an addon. It then returns whether or not the addon is currently loaded by the game
client. When there are distinct choices for the function signature, each signature is
addedtotheendinthisway.
Argument and Return Listings
Following a function signature is a detailed listing of the arguments and returns for
the given function. The arguments and returns are both given in a similar format. Here
is the listing for the GetSocketTypes() function:
Argument:
indexThe index of the socket to query. (number)
Chapter 27 API Reference 541
Return:
gemColorThe color of the given gem socket. (string)
Blue
Yellow
Red
Meta
Under each section is a list of named arguments, followed by a description of the
argument. After the description is an indicator that tells you which type of Lua value
to pass (or what type to expect from the function). In this case, the function accepts a
numeric argument called index and returns a string that is the color of the socket. If
the argument is optional, this will be indicated in the argument listing as well as in the
function signature.
Common API Flags
Throughout the API, there are a number of common attributes that a given function
might have, for example those functions that cannot be called by addons during
combat. Table 27-1 shows a listing of the various API flags.
When a function is flagged with one of the API flags, you will see a margin icon
indicating this. Although most flags are self explanatory, you can always refer back to
Table 27-1 for more information.
Table 27-1: API Flags
FLAG DESCRIPTION
blizzardui This function is not a C API but a Lua function declared in
Blizzard’s default user interface. Its implementation can be
viewed by extracting the addon data using the Addon Kit
provided by Blizzard.
confirmation This function does not prompt the user for confirmation
before its results take effect -- that behavior is provided by
the default UI, and this function is called from the
confirmation dialog
hardware This function requires a key or mouse press in order to be
used, but may not be protected.
luaapi This function is defined in the Lua standard libraries
maconly This function is designed for the Mac OS X client only.
nocombat This function cannot be called during combat.
protected This function is protected and can only be called by the
Blizzard user interface.
542 Part IV Reference
API Meta-Types
To clarify the documentation of API functions, we have created a number of meta-types
that are used to describe what sort of values are accepted in an argument or returned
from an API function. These are not actual Lua types, but a classification of accepted
values in various API sub-systems. When a meta-type applies to an argument or return
value, this is indicated after the Lua type in the argument listing. Meta-types enable
you to consolidate the documentation for classes of API functions, rather than having to
document the same list of values over and over again. This section describes these types.
1nil
Many API functions use values indicative of a binary state but do not utilize the
Boolean true and false values in Lua. Due to the way the functions are limited, they
use the number value 1for true,andnil for false. Because Lua treats nil as a false
value and any non-nil value as true in a conditional, these values can generally be
used the same as Boolean values in conditional statements (such as if IsInGuild()
then ... end). However, you should avoid making direct comparisons using this
type of value: for example, the condition if IsInGuild() == true then ... end
will never be triggered. These types of variables are called 1nil values, to distinguish
them from Boolean values.
actionID
The actionID meta-type is used to identify one of the player’s action bar slots. In
UI terms, action bar slots are a layer of abstraction between spells or items and the
mechanisms available to the player for using them conveniently. For example, instead
of the default UI internally using SetBindingSpell(),SetBindingMacro(),and
so on whenever the player changes the contents of the visible action bars, it instead
manages a set of key bindings corresponding to the action bar slots.
Chapter 27 API Reference 543
Every player has at least NUM_ACTIONBAR_PAGES *NUM_ACTIONBAR_BUTTONS (in
the current client, 6*12,or72) action slots corresponding to the six default
action bar pages. In addition, players of certain classes (or with certain talents) may
have additional actionIDs available corresponding to the ‘‘bonus’’ action bars that
automatically become available when changing stances, stealthing, shapeshifting, etc.
ah-list-type
There are three different types of auction house listings, represented by string values.
These ah-list-type values may be one of the following:
listThe items that are currently for sale in the auction house.
bidderThe items for which the player has placed a bid.
ownerThe items that the player has placed up for auction.
anchorPoint
Frames and graphical regions are anchored to each other using anchor points, repre-
sented by the anchorPoint meta-type. These points are simple strings that indicate a
point on the region. The following are valid anchor point strings:
CENTER LEFT BOTTOMRIGHT
BOTTOM RIGHT TOPLEFT
TOP BOTTOMLEFT TOPRIGHT
arenaTeamID
The arenaTeamID API meta-type identifies one of the (up to three) arena teams to
which a player can belong. These indices begin at 1for the player’s smallest team and
increase with size. For example, if the player belongs to a 2v2 team and a 5v5 team
then 1will indicate the 2v2 team while 2refers to the 5v5 team. However, if the player
belongs to a 3v3 team and a 5v5 team but no 2v2 team, then 1will indicate the 3v3
team, and 2will again indicate the 5v5 team. If the player is on teams of all three sizes,
then 1indicates the 2v2 team, 2indicates the 3v3 team and 3indicates the 5v5 team.
The Blizzard UI’s Lua function ArenaTeam_GetTeamSizeID can be used to translate
a team size (2, 3, or 5) to the appropriate arenaTeamID for the player.
auraFilter
Buffs and debuffs can be filtered in the WoW API using strings that represent complex
aura filters, indicated by the auraFilter meta-type. These strings can contain any
number of filterers separated by either the pipe character (|) or a space. Possible filter
values currently include:
HELPFULHelpful spells (buffs).
HARMFULHarmful spells (debuffs).
PLAYERSpells that can be cast by the player on themselves.
544 Part IV Reference
RAIDSpells that can be cast by the player on their raid.
CANCELABLESpells that can be cancelled.
NOT_CANCELABLESpells that cannot be cancelled.
For example the string HELPFUL|RAID will filter to show only those helpful spells
that the player can cast on their raid. You cannot use both the HARMFUL and the
HELPFUL filters at the same time, as they cancel each other out. In addition, these two
filters should not be used in the UnitBuff and UnitDebuff functions, as they are
already implicitly included in their implementation and as such will be ignored.
backdrop
Abackdrop definition is a Lua table with specific attributes that match directly with
the elements in the <Backdrop> definition in an XML definition. It has the following
structure:
{
-- path to the background texture
bgFile = “Interface\\DialogFrame\\UI-DialogBox-Gold-Background“,
-- path to the border texture
edgeFile = “Interface\\DialogFrame\\UI-DialogBox-Gold-Border“,
-- true to repeat the background texture to fill the frame, i
false to scale it
tile = true,
-- size (width or height) of the square repeating background i
tiles (in pixels)
tileSize = 32,
-- thickness of edge segments and square size of edge corners i
(in pixels)
edgeSize = 32,
-- distance from the edges of the frame to those of the background i
texture (in pixels)
insets = {
left = 11,
right = 12,
top = 12,
bottom = 11
}
}
bitfield
Abitfield is a numeric value combining several binary flags into one number. The
flags can be inspected individually using the bitwise functions in the bit library. For
example (using GetItemFamily and related constants):
GetItemFamily(“Crystallized Air“)
-- returns 1224
bit.bor(0x0008,0x0040,0x0080,0x0400)
-- returns 1224
-- these are the masks for tradeskill bags.
Chapter 27 API Reference 545
bit.band(GetItemFamily(“Crystallized Air“), 0x0040)
-- returns 64, or 0x0040: the item fits in an Enchanting Bag
bit.band(GetItemFamily(“Crystallized Air“), 0x0020)
-- returns 0, or 0x0000: the item does not fit in an Herb Bag
binding
Abinding is a string identifying one or more keyboard keys or mouse buttons, used
with key binding and modified click API functions and the OnKeyDown/OnKeyUp script
handlers. Most letter, number, and symbol keys are identified by their (uppercase)
letter, number, or symbol.
Other keys are identified by a series of global variables with names prefaced
by KEY_; for instance, the localized name for the binding NUMPAD0 can be found
in _G[“KEY_NUMPAD0“]. Some keys have platform-specific names; for example, the
localized name for the binding PRINTSCREEN can be found in _G[“KEY_PRINTSCREEN
_MAC“] (revealing that it refers to the F13 key found on Mac extended keyboards).
Modifier keys are identified as follows:
LSHIFT,RSHIFT,SHIFTLeft, right, or generic Shift key
LCTRL,RCTRL,CTRLLeft, right, or generic Control key
LALT,RALT,ALTLeft, right, or generic Alt (or Option) key
STRGGerman equivalent to CTRL key
Mouse buttons are identified by the token BUTTON followed by the but-
ton numberBUTTON1 for the primary (left) button, BUTTON2 for the right
button, BUTTON3 for middle, and so on.
For use in key bindings, several key/button identifiers can be strung together
with hyphens to indicate a key combination; e.g. CTRL-SHIFT-SPACE,RALT-F12,
SHIFT-BUTTON1.
chatMsgType
The chatMsgType is a string identifying the common type of a set of chat window
messages; used in chat window functions for determining which windows display
which messages, and the colors for displaying each message type.
Each CHAT_MSG event has a corresponding chatMsgType identified by the part of
the event name following the initial CHAT_MSG_;e.g.thechatMsgType for CHAT_MSG
_COMBAT_FACTION_CHANGE is COMBAT_FACTION_CHANGE. A list of pre-configured
chatMsgTypes can be found as keys in the global table ChatTypeInfo.
colorString
Formatting used to colorize sections of text when being displayed in a FontString.
AcolorString takes the form |c(colorvalue)(text)|r:
colorvalueA string of four hexadecimal formatted bytes describing
component values of the color. Each byte can be a value from 00 (representing
546 Part IV Reference
zero intensity of the component) to ff (representing full intensity of the
component):
1. Alpha value, but currently unused: always ff
2. Red component of the color
3. Green component of the color
4. Blue component of the color
textThe text to be colorized.
For example the string |cffffff00Yellow Text|r will display yellow text when
sent to a font string or message frame. Color strings can be used for display anywhere
in the UI, but can only be delivered in a chat message if included as part of a hyperlink.
containerID
AcontainerID is a numeric identifier for one of the player’s bags or other containers.
Possible values:
-2—Keyring
-1Main storage area in the bank
0Backpack
In addition a number from 1through NUM_BAG_SLOTS indicates a bag slot, num-
bered as presented in the default UI from right to left. Container identifiers from
NUM_BAG_SLOTS + 1 through NUM_BAG_SLOTS + NUM_BANKBAGSLOTS represent the
bank bag slots, numbered as presented in the default UI from left to right.
containerSlotID
AcontainerSlotID is a numeric index of an item slot within a container. Slots are
numbered from left to right, top to bottom, as presented in the default UI.
frameStrata
AframeStrata value is a string identifying the general layering order of frames.
Where frame level provides fine control over the layering of frames, frame strata
provides a coarser level of layering control. Frames in a higher strata always appear
‘‘in front of’’ frames in lower strata regardless of frame level. Available frame strata
are listed below in order from lowest to highest:
BACKGROUNDUsed by default for static UI elements such as the PlayerFrame
and Minimap
LOWUsed by default for lower-priority UI elements such as the party member
and target frames
MEDIUMDefault frame strata for general usage
HIGHUsed by default for higher-priority UI elements such as the Calendar and
Loot frames
DIALOGUsed by default for alerts and other dialog boxes which should appear
over nearly all other UI elements
Chapter 27 API Reference 547
FULLSCREENUsed by default for full-screen windows such as the World Map
FULLSCREEN_DIALOGUsed by default for alerts or dialog boxes which should
appear even when a full-screen window is visible
TOOLTIPUsed for mouse cursor tooltips, ensuring they appear over all other
UI elements
glyphIndex
AglyphIndex is a numeric glyph index, ordered by the level at which the glyphs are
discovered. Specifically:
1. The major glyph at the top of the user interface (level 15)
2. The minor glyph at the bottom of the user interface (level 15)
3. The minor glyph at the top left of the user interface (level 30)
4. The major glyph at the bottom right of the user interface (level 50)
5. The minor glyph at the top right of the user interface (level 70)
6. The major glyph at the bottom left of the user interface (level 80)
GUID (Globally Unique IDentifier)
Each entity in World of Warcraft is identified by a globally unique identifier (GUID), a
unique 64-bit number that is generally presented as a string containing a hexadecimal
representation of the number (e.g. ‘‘0xF530007EAC083004’’). (Note that Lua in WoW
does not support 64-bit integers, so this value cannot be converted in a lossless way
with tonumber.)
The type of unit represented by a GUID can be determined by using bit.band()
to mask the first three digits with 0x00F:
0x000—A player
0x003—An NPC
0x004A player’s pet (i.e. hunter/warlock pets and similar; non-combat pets
count as NPCs)
0x005—A vehicle
Further content of the GUID varies by unit type: player, NPC, pet, or vehicle.
Players
The remaining thirteen digits are unique to a player character at least within that
character’s battlegroup (that is, they remain unique and constant even in cross-server
battlegrounds). This number is also semi-permanentit persists from character cre-
ation until deletion, renaming, or server transfer.
NPCs
For NPCs, the remaining digits break down as follows:
Digits 4-6Unused.
548 Part IV Reference
Digits 7-10NPC creature ID: identifies the specific named NPC (e.g. Hogger,
Loque’nahak) or type of NPC (e.g. Sunfury Nethermancer, Shattertusk Mam-
moth). Converting to decimal results in the ID found on database sites such
as http://wowhead.com; can also be used with the PlayerModel widget API
SetCreaturetoviewtheNPCsmodel.
Digits 11-16Spawn counter: identifies the individual NPC (i.e. differentiates
between the Gamon you recently killed and the Gamon that respawned a few
minutes later.
Pets
Hunter pets immediately after taming retain the GUID they had as a wild creature;
after re-summoning or logout/login, their GUID changes to the pet format. Remaining
digits can be broken down as follows:
Digits 4-10A constant value unique to the individual pet: like a player’s unique
ID it is constant across multiple sessions.
Digits 11-16Spawn counter: changes when the pet is dismissed and re-
summoned.
Vehicles
Vehicles have the same format and content as NPCs.
GUID Example
For example, the GUID 0xF530007EAC083004 can be deconstructed as follows:
Digits 1-3 are ‘‘F53’’; bit.band(0xF53, 0x00F) == 0x003,sothisisanNPC.
Digits 7-10 are ‘‘7EAC’’; 0x7EAC == 32428, which you can look up to find the NPC
is an Underbelly Rat.
Digits 11-16 have no intrinsic meaning, but distinguish this Underbelly Rat from all
others spawned since the last server reset.
The following code is an example of a function to decode GUIDs:
function ParseGUID(guid)
local first3 = tonumber(“0x“..strsub(guid, 3,5))
local unitType = bit.band(first3,0x00f)
if (unitType == 0x000) then
print(“Player, ID #“, strsub(guid,6))
elseif (unitType == 0x003) then
local creatureID = tonumber(“0x“..strsub(guid,9,12))
local spawnCounter = tonumber(“0x“..strsub(guid,13))
print(“NPC, ID #“,creatureID,“spawn #“,spawnCounter)
elseif (unitType == 0x004) then
local petID = tonumber(“0x“..strsub(guid,6,12))
local spawnCounter = tonumber(“0x“..strsub(guid,13))
print(“Pet, ID #“,petID,“spawn #“,spawnCounter)
elseif (unitType == 0x005) then
Chapter 27 API Reference 549
local creatureID = tonumber(“0x“..strsub(guid,9,12))
local spawnCounter = tonumber(“0x“..strsub(guid,13))
print(“Vehicle, ID #“,creatureID,“spawn #“,spawnCounter)
end
end
Hyperlink
Ahyperlink is a string containing markup allowing the client to present it as a link,
which the player can click to view more information about or take action regarding
the data it represents.
Hyperlinks take the form |H(linktype):(linkdata)|h(text)|h,where
(linktype) determines the type of link, (linkdata) is a code referencing the linked
information, and (text) is the text visible to the player. Some API functions which
operate on links do not require a full hyperlink, only its linktype:linkdata portion.
Links are often encapsulated in a colorString. In such cases, the full color
String-wrapped link is the only form of the link allowed to be used in chat;
attempting to transmit an invalid link may cause the player to be disconnected from
the server.
The WoW client recognizes several kinds of hyperlinks, identified by their linktype:
player spell talent item
playerGM enchant achievement
glyph quest trade
They are described in the following sections. If linkdata elements noted as optional
are omitted the client can still resolve the link.
player
Example: |Hplayer:Aerdrig|h[Aerdrig]|h
Represents a player character. Left-clicking a player link in the default UI opens the
ChatFrameEditBox to send a whispered message to the character. Right-clicking opens
a menu with options for inviting the character to the player’s party/raid, adding the
character to the ignore list, or reporting the chat message in which the link appears
as spam. The linkdata for a player link consists solely of the player’s name (or in
cross-realm battlegrounds, the player’s name and home realm separated by a hyphen,
e.g. ‘‘Gundark-Broxigar’’).
playerGM
Example: |HplayerGM:Eyonix|h[Eyonix]|h
A variation on the player type used exclusively for Game Master chat.
glyph
Example: |cff66bbff|Hglyph:23:460|h[Glyph of Fortitude]|h|r
550 Part IV Reference
Represents a glyph inscribed in a character’s spellbook. Clicking a glyph link in the
default UI shows a tooltip with its description. The linkdata for a glyph link follows
the format socket:glyphID:
socket (optional)The socket in which the glyph is placed; values 21 through
26 correspond to glyphIndex values 1 through 6.
glyphIDA unique identifier for the glyph effect; not used elsewhere in the API.
spell
Example: |cff71d5ff|Hspell:46584|h[Raise Dead]|h|r
Represents a spell. Clicking a spell link in the default UI shows a tooltip with its
description. The linkdata for a spell link consists solely of the spellID number uniquely
identifying the spell, usable with APIs such as GetSpellInfo().
enchant
Example: |cffffd000|Henchant:59387|h[Certificate of Ownership]|h|r
Represents a trade skill recipe (originally used only for Enchanting, but now applies
to all trade skills). Clicking a spell link in the default UI shows a tooltip with its
description (and that of the item it creates, if applicable). The linkdata for a spell link
consists solely of the spellID number uniquely identifying the trade skill recipe, usable
with APIs such as GetSpellInfo().
quest
Example: |cffffff00|Hquest:982:17|h[Deep Ocean, Vast Sea]|h|r
Represents a quest from a character’s quest log. Clicking a quest link in the default UI
shows a tooltip with a brief description of the quest and its objectives. When the client
displays a quest link sent by another character, it automatically alters the enclosing
colorString to reflect the difficulty of the quest relative to the player’s level. The
linkdata for a quest link follows the format questID:level:
questIDA unique numeric identifier for the quest. This number corresponds
with the numbers found on data sites such as http://wowhead.com.
level (optional)Recommended character level for attempting the quest. (A
level of -1 means the quest is appropriate for any level; used for holiday quests.)
talent
Example: |cff4e96f7|Htalent:1396:4|h[Unleashed Fury]|h|r
Represents a talent. Clicking a talent link in the default UI shows a tooltip with its
description. The linkdata for a talent link follows the format talentID:points:
talentIDA unique identifier for the talent; not used elsewhere in the API.
rank (optional)Number of points spent in the talent, minus one: if this value
is omitted or -1, the tooltip shows the talent as it appears in the Talents UI when
zero points have been spent; if this value is 0, the tooltip shows the talent as it
appears when one point has been spent on it. Values greater than the number of
available ranks for a talent are interpreted as -1.
Chapter 27 API Reference 551
achievement
Example: |cffffff00|Hachievement:2336:060000000279E425:1:10:14:8:429
4967295:4294967295:4294967295:4294967295|h[Insane in the Membrane]
|h|r
Represents an achievement earned or in progress by a player. Clicking an
achievement link in the default UI shows a tooltip with a summary of the achievement
and (if applicable) its criteria. The linkdata for an achievement link follows the for-
mat achievementID:playerGUID:completed:month:day:year:bits1:bits2:
bits3:bits4. If only the first element achievementID is specified, the client
resolving the link will show the player’s progress or completion of the achievement;
otherwise, all elements are required:
achievementIDA unique identifier for the achievements; usable with various
Achievement API functions.
playerGUID (optional)GUID of a player character whose progress or comple-
tion of the achievement is linked (return value of UnitGUID() without the ‘‘0x’’
prefix).
completed (optional)1if the character has completed the achievement; other-
wise 0.
month (optional)Index of the month (1=January) in which the character
completed the achievement, or 0if the achievement is incomplete.
day (optional)Day of the month on which the character completed the achieve-
ment, or 0if the achievement is incomplete.
year (optional)Year (two-digit year) in which the character completed the
achievement, or -1 if the achievement is incomplete.
bits1,bits2,bits3,bits4 (optional)Encoded data fields interpreted by the
client to show completion of achievement criteria.
trade
Example: |cffffd000|Htrade:45361:339:375:60000000279E425:Q/nPf6nprU3
/n/fA8/Bw/PA+/B+/Aw/HA+/Bw/HA+5nfg////////P////HAAAQAA+DAAAAAAA|
h[Inscription]|h|r
Represents the entire list of recipes for a character’s trade skill or profession. The
linkdata for an achievement link follows the format spellID:skill:maxSkill:
playerGUID:data. All elements are required:
spellID—The spellID number uniquely identifying the trade skill and its rank
(e.g. Apprentice Tailoring vs. Journeyman Tailoring), usable with APIs such as
GetSpellInfo().
skillThe character’s current skill in the profession
maxSkillThe maximum skill for the character’s current rank in the profession
(e.g. 375 for Master rank).
playerGUIDGUID of the character whose profession is linked (return value of
UnitGUID() without the ‘‘0x’’ prefix).
552 Part IV Reference
data Encoded data field interpreted by the client to show the character’s list
of known trade skill recipes.
item
Examples: |cffa335ee|Hitem:45457:3828:3395:3395:0:0:0:0:80|h[Staff
of Endless Winter]|h|r,|cff1eff00|Hitem:36360:0:0:0:0:0:-37:16338
78093:80|h[Frostpaw Legguards]|h|r
Represents an item. Clicking an item link in the default UI shows a tooltip
with information about the item. Control-clicking an equippable item opens the
DressUpFrame to preview how the item would look on the player character if
equipped. The linkdata for an item link follows the format itemID:enchant:
gem1:gem2:gem3:gem4:suffixID:uniqueID:level:
itemID—The items itemID.
enchant (optional)Unique identifier of the enchantment applied to the item;
not used elsewhere in the API.
gem1,gem2,gem3,gem4 (optional)Unique identifiers of the enchantments
provided by gems socketed in the item (not the itemIDs of the gems themselves);
not used elsewhere in the API.
suffixID (optional)Identifies the specific variation represented for
random-property items (e.g. ‘‘... of the Monkey’’, ‘‘... of Frost Protection’’, etc.).
A positive number indicates a variation with specific stat values (e.g. 1200 =‘‘of
the Bear’’, 8 stamina 8 strength; 1220 =‘‘of the Bear’’, 14 stamina 15 strength);
a negative number indicates a type of variation, with actual stat values to be
determined by decoding the uniqueID.
uniqueID (optional)A number used internally by the WoW client/server
architecture to track a specific occurrence of an item: used for crafted items which
display ‘‘<Made by Name>’’ in their tooltips and for random-property items. For
items with a negative suffixID,usingbit.band(uniqueID, 0xFFFF) reveals
the factor used to calculate the item’s stats.
levelLevel of the character linking the item; used for ‘‘Heirloom’’ items whose
stats change based on the level of the character equipping them.
inventoryID
An inventoryID identifies an inventory slot used (mostly) for the equipping of items.
Inventory ID numbers exist not only for the armor and weapon slots seen in the default
UI’s character window, but also for bag slots, bank bag slots, the contents of the bank’s
main storage area, and the contents of the keyring. Inventory slots are not defined
as constants in the default UI; to obtain the inventoryID for a slot, use one of the
following functions:
GetInventorySlotInfo
BankButtonIDToInvSlotID
ContainerIDToInventoryID
KeyRingButtonIDToInvSlotID
Chapter 27 API Reference 553
itemID
The itemID uniquely identifies an item; usable with APIs such as GetItemInfo().
These identifiers match those utilized on database sites such as http://wowhead.com.
itemLocation
The itemLocation is a bitfield describing the location of an item owned by the
player. The following example code illustrates masks that can be compared with an
itemLocation to determine the exact location described:
local ITEM_INVENTORY_PLAYER = 0x00100000
local ITEM_INVENTORY_BACKPACK = 0x00200000
local ITEM_INVENTORY_BAGS = 0x00400000
local ITEM_INVENTORY_BANK = 0x00800000
local MASK_BAG = 0xf00
local MASK_SLOT = 0x3f
local bagMap = {
[0x100] = 1,
[0x200] = 2,
[0x400] = 3,
[0x800] = 4,
}
local function ItemInBag(itemLocation)
if bit.band(itemLocation, ITEM_INVENTORY_BAGS) > 0 then
local bag = bagMap[bit.band(itemLocation, MASK_BAG)]
local slot = bit.band(itemLocation, MASK_SLOT)
return bag, slot
elseif bit.band(itemLocation, ITEM_INVENTORY_BACKPACK) > 0 then
local slot = bit.band(itemLocation, MASK_SLOT)
return 0, slot
end
end
local function ItemEquipped(itemLocation)
if bit.band(itemLocation, ITEM_INVENTORY_PLAYER) > 0 then
local slot = bit.band(itemLocation, MASK_SLOT)
return slot
end
end
itemQuality
itemQuality, unsurprisingly, indicates the quality (or rarity) of an item. Possible
values and examples:
1. Poor (gray): Broken I.W.I.N. Button
2. Common (white): Archmage Vargoth’s Staff
3. Uncommon (green): X-52 Rocket Helmet
4. Rare / Superior (blue): Onyxia Scale Cloak
554 Part IV Reference
5. Epic (purple): Talisman of Ephemeral Power
6. Legendary (orange): Fragment of Val’anyr
7. Artifact / Heirloom (light yellow): Bloodied Arcanite Reaper
itemString
An itemString refers to the linktype:linkdata portion of an item link (the part
containing the itemID,e.g.item:19019); see the hyperlink meta-type for more details.
justifyH
justifyH is a string describing the horizontal justification of text within a widget.
Possible values: LEFT,CENTER,RIGHT.
justifyV
justifyV is a string describing the vertical justification of text within a widget.
Possible values: TOP,MIDDLE,BOTTOM.
layer
layer is a string identifying the layer in which a region’s graphics are drawn relative
to those of other regions in the same frame; graphics in higher layers (as listed below)
are drawn ‘‘on top of’’ those in lower layers.
BACKGROUNDFirst (lowest) layer
BORDERSecond layer
ARTWORKThird layer; default for regions for which layer is not specified
OVERLAY—Fourth layer
HIGHLIGHTFifth (highest) layer; regions in this layer are automatically shown
when the mouse is over the containing Frame (if the Frame’s enableMouse
property is true).
macroID
The macroID is an index of one of the player’s saved macros. Macros shared by all
characters on player’s account are indexed from 1to MAX_ACCOUNT_MACROS;macros
specific to the current character are indexed from MAX_ACCOUNT_MACROS + 1 to
MAX_ACCOUNT_MACROS + MAX_CHARACTER_MACROS.
powerType
The powerType meta-type is used to indicate one of the different power types that
characters can have. Possible values are:
0. Mana
1. Rage
2. Focus
3. Energy
4. Happiness
5. Runes
6. Runic Power
Chapter 27 API Reference 555
rollID
The default user interface assigns a unique numeric identifier for all items that are
able to be rolled on by the party. This identifier can be obtained by checking the
rollID member of the specific group loot frame. For example: /run print(Group
LootFrame1.rollID).
spellbookID
spellbookID is an index of a spell in the player’s (or pet’s) spellbook; usable with
APIs such as GetSpellInfo().
spellID
spellID is a globally unique number that identifies a spell (and its rank). It is usable
with APIs such as GetSpellInfo(), and is also useful with database sites.
standingID
The standingID identifies a level of reputation:
1. Hated
2. Hostile
3. Unfriendly
4. Neutral
5. Friendly
6. Honored
7. Revered
8. Exalted
The default UI provides constants which can be helpful in displaying standing
information.
The localized name for the standing Ncan be found in the global variable
FACTION_STANDING_LABELN or FACTION_STANDING_LABELN_FEMALE;e.g.FACTION
_STANDING_LABEL4 == “Neutral“.
NOTE Although the male (unlabeled) and female forms are the same in the enUS
client, the same is not true for other languages. Be sure to use the appropriate
form for the character’s gender.
Color values for each standing (as seen in reputation status bars in the default UI)
can be found in the table FACTION_BAR_COLORS.
unitID
You see unitID used throughout the API to identify units of interest. Possible values:
playerThe player him/herself
petThe player’s pet
vehicleThe vehicle currently controlled by the player
targetThe player’s current target
focusThe player’s focused unit (as can be set by typing /focus name)
556 Part IV Reference
mouseoverThe unit currently under the mouse cursor (applies to both unit
frames and units in the 3D world)
npcThe unit the player is currently interacting with (via the Merchant, Trainer,
Bank, or similar UI); not necessarily an NPC (e.g. also used in the Trade UI)
party1 to party4Another member of the player’s party. Indices match the
order party member frames are displayed in the default UI (party1 is at the top,
party4 at the bottom), but are not consistent among party members (i.e. if Thrall
and Cairne are in the same party, the player Thrall sees as party2 may not be the
same player Cairne sees as party2).
partypet1 to partypet4A pet belonging to another member of the player’s
party
raid1 to raid40A member of the player’s raid group. Unlike with the party
tokens, one of the raid unit IDs will belong to the player. Indices have no relation
to the arrangement of units in the default UI.
raidpet1 to raidpet40A pet belonging to a member of the player’s raid
group
arena1 to arena5A member of the opposing team in an Arena match
AunitID can also be formed by appending ‘‘target’’ to an existing unitID, referring
to that unit’s target. This can be done repeatedly. For example, consider a raid situation
where the token raid13 refers to a priest: raid13target might be a rogue the priest
is healing, raid13targettarget might be the boss monster the rogue is attacking,
and raid13targettargettarget might be the warrior tanking the boss.
Many (but not all) API functions that accept a unitID also accept the name of a
unit (assuming that unit is in the player’s party or raid). For example, UnitHealth
(“Cladhaire“) will return the same value as UnitHealth(“party1“) if the unit
party1 is the player named Cladhaire. In such situations, a unit’s target can still be
accessed by appending -target; for example, UnitHealth(“Cladhaire-target“).
API Reference
Confirmation AbandonQuest
Confirms abandoning a quest.
Use SetAbandonQuest() first to select the quest to abandon.
Confirmation AbandonSkill
Unlearns a skill (used only for professions).
AbandonSkill(index)
Arguments:
indexIndex of an entry in the skills list (between 1and GetNumSkill
Lines())(number)
AcceptAreaSpiritHeal
Accepts the next upcoming periodic resurrection from a battleground spirit
healer.
Chapter 27 API Reference 557
Automatically called in the default UI in response to the AREA_SPIRIT
_HEALER_IN_RANGE event which fires when the player’s ghost is near a
battleground spirit healer.
AcceptArenaTeam
Acceptsaninvitationtojoinanarenateam.
Hardware AcceptBattlefieldPort
Accepts the offered teleport to a battleground/arena or leaves the
battleground/arena or queue.
AcceptBattlefieldPort(index, accept)
This function requires a hardware event when used to accept a teleport; it can
be called without a hardware event for leaving a battleground/arena or its
queue.
Arguments:
indexIndex of a battleground or arena type for which the player is queued
(number)
accept1to accept the offered teleport; nil to exit the queue
or leave the battleground/arena match in progress (1nil)
AcceptDuel
Accepts a proposed duel.
AcceptGroup
Accepts an invitation to join a party or raid.
Usable in response to the PARTY_INVITE_REQUEST event which fires when the
player is invited to join a group. This function does not automatically hide
the default UI’s group invite dialog; doing such requires calling StaticPopup
_Hide(“PARTY_INVITE“),butonlyafterthePARTY_MEMBERS_CHANGED event
fires indicating the player has successfully joined the group.
AcceptGuild
Accepts an invitation to join a guild.
Usable in response to the GUILD_INVITE_REQUEST event, which fires when
the player is invited to join a guild.
AcceptLFGMatch
Accepts a proposed LFG match.
Usable after a group match has been proposed to the player via the
LFG_MATCH_REQUEST event.
AcceptLevelGrant
Accepts a level offered by the player’s Recruit-a-Friend partner.
AcceptQuest
Accepts the quest offered by a questgiver.
Usable following the QUEST_DETAIL event in which the questgiver presents
the player with the details of a quest and the option to accept or decline.
558 Part IV Reference
AcceptResurrect
Accepts an offered resurrection spell.
Not used for self-resurrection; see UseSoulstone() for such cases.
Confirmation AcceptSockets
Accepts changes made in the Item Socketing UI.
Any gems added are permanently socketed into the item, and any existing
gems replaced by new gems are destroyed. This function only has effect while
the Item Socketing UI is open (i.e. between the SOCKET_INFO_UPDATE and
SOCKET_INFO_CLOSE events).
AcceptTrade
Accepts a proposed trade.
Once both players have accepted, the trade process completes and the actual
exchange of items/money/enchants takes place.
Confirmation AcceptXPLoss
Resurrects the player at a spirit healer, accepting possible consequences.
Resurrecting at a spirit healer generally results in a loss of durability (both
equipped items and those in the player’s bags) and may also result in the
Resurrection Sickness debuff.
Early in the development of World of Warcraft, resurrecting at a spirit healer
caused a loss of experience points. The change to a loss of item durability was
made before the initial public release of World of Warcraft, but the name of this
function was never changed.
ActionHasRange
Returns whether an action has a range restriction.
hasRange = ActionHasRange(slot)
Arguments:
slotAn action bar slot (number,actionID)
Returns:
hasRange1if the action has a range restriction; otherwise nil (1nil)
AddChatWindowChannel
Adds a chat channel to the saved list of those displayed in a chat window.
zoneChannel = AddChatWindowChannel(index, channel)
Used by the default UI’s function ChatFrame_AddChannel() which manages
the set of channel messages shown in a displayed ChatFrame.
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
channelName of a chat channel (number)
Returns:
zoneChannel0for non-zone channels, otherwise a numeric index specific to
that channel (number)
Chapter 27 API Reference 559
AddChatWindowMessages
Adds a message type to the saved list of those displayed in a chat window.
AddChatWindowMessages(index, “messageGroup“)
Used by the default UI’s function ChatFrame_AddMessageGroup(),which
manages the set of message types shown in a displayed ChatFrame.
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
messageGroupToken identifying a message type (string, chatMsgType)
AddFriend
Adds a character to the friends list.
AddFriend(“name“)
Arguments:
nameName of a character to add to the friends list (string)
AddIgnore
Adds a character to the ignore list.
AddIgnore(“name“)
Arguments:
nameName of a character to add to the ignore list (string)
AddMute
Adds a character to the muted list for voice chat.
AddMute(“name“)
The Muted list acts for voice chat as the Ignore list does for text chat: muted
characters will never be heard regardless of which voice channels they join the
player in.
Arguments:
nameName of a character to add to the mute list (string)
AddOrDelIgnore
Adds the named character to the ignore list, or removes the character if already
in the ignore list.
AddOrDelIgnore(“fullname“)
Arguments:
fullnameName of a character to add to or remove from the ignore list
(string)
AddOrDelMute
Adds or removes a character from the voice mute list.
AddOrDelMute(“unit“) or AddOrDelMute(“name“)
Adds the character to the list if he/she is not already on it; removes the
character if already on the list.
560 Part IV Reference
The Muted list acts for voice chat as the Ignore list does for text chat: muted
characters will never be heard regardless of which voice channels they join the
player in.
Arguments:
unitA unit to mute (string,unitID)
nameName of a character to mute (string)
AddOrRemoveFriend
Adds the named character to the friends list, or removes the character if
already in the friends list.
AddOrRemoveFriend(“name“, “note“)
Arguments:
nameName of a character to add to or remove from the friends list (string)
noteNote text to be associated with the friends list entry created (string)
AddPreviewTalentPoints
Spends (or unspends) talent points in the Talent UI’s preview mode.
AddPreviewTalentPoints(tabIndex, talentIndex, points, isPet, i
talentGroup)
Arguments:
tabIndexIndex of a talent tab (between 1and GetNumTalentTabs())
(number)
talentIndexIndex of a talent option (between 1and GetNumTalents())
(number)
pointsNumber of points to spend on the talent, or a negative num-
ber to unspend points. Values larger than allowed for the talent will be
clipped to the maximum value (e.g. attempting to spend ten points on a
talent that has five ranks will only spend up to five points). (number)
isPetTrue to edit talents for the player’s pet, false to edit talents for the
player (boolean)
talentGroupWhich set of talents to edit, if the player has Dual Talent Special-
ization enabled (number)
1Primary Talents
2—Secondary Talents
nilCurrently active talents
AddQuestWatch
Adds a quest to the objectives tracker.
AddQuestWatch(questIndex)
Arguments:
questIndexIndex of a quest in the quest log (between 1and
GetNumQuestLogEntries())(number)
AddTrackedAchievement
Adds an achievement to the objectives tracker UI.
AddTrackedAchievement(id)
Chapter 27 API Reference 561
Arguments:
idThe numeric ID of an achievement (number)
AddTradeMoney
Adds the money currently on the cursor to the trade window.
ApplyBarberShopStyle
Purchases the selected barber shop style changes.
Does not exit the barber shop session, so further changes are still allowed.
The BARBER_SHOP_SUCCESS and BARBER_SHOP_APPEARANCE_APPLIED
events fire once the style change takes effect.
ArenaTeamDisband
Disbands an arena team.
ArenaTeamDisband(team)
Only has effect if the player is captain of the given team.
Arguments:
teamIndex of one of the player’s arena teams (number,arenaTeamID)
ArenaTeamInviteByName
Invites a character to one of the player’s arena teams.
ArenaTeamInviteByName(team, “name“)
Arguments:
teamIndex of one of the player’s arena teams (number,arenaTeamID)
nameName of a character to invite (string)
Confirmation ArenaTeamLeave
Leaves an arena team.
ArenaTeamLeave(team)
Arguments:
teamIndex of one of the player’s arena teams (number,arenaTeamID)
ArenaTeamRoster
Requests arena team roster information from the server.
ArenaTeamRoster(team)
Does not return information directly: the ARENA_TEAM_ROSTER_UPDATE event
fires when information from the server becomes available, which can then be
retrieved using GetNumArenaTeamMembers() and
GetArenaTeamRosterInfo().
Roster update requests are limited to once every 10 seconds per team.For
example, calling ArenaTeamRoster(1) twice within ten seconds will not
result in a second ARENA_TEAM_ROSTER_UPDATE event, but calling
ArenaTeamRoster(1) and ArenaTeamRoster(2) within ten seconds will
result in two ARENA_TEAM_ROSTER_UPDATE events (one for each team).
Arguments:
teamIndex of one of the player’s arena teams (number,arenaTeamID)
562 Part IV Reference
Confirmation ArenaTeamSetLeaderByName
Promotes an arena team member to team captain.
ArenaTeamSetLeaderByName(team, “name“)
Only has effect if the player is captain of the given team.
Arguments:
teamIndex of one of the player’s arena teams (number,arenaTeamID)
nameName of a team member to promote (string)
Confirmation ArenaTeamUninviteByName
Removes a member from an arena team.
ArenaTeamUninviteByName(team, “name“)
Arguments:
teamIndex of one of the player’s arena teams (number,arenaTeamID)
nameName of a team member to remove (string)
ArenaTeam_GetTeamSizeID
Converts an arena team size to the appropriate numeric arena team identifier.
teamID = ArenaTeam_GetTeamSizeID(teamSize)
Arguments:
teamSizeThe size of the arena team (i.e. 2 for 2v2, 3 for 3v3, etc.) (number)
Returns:
teamIDThe numeric identifier for the arena team of the given size (number,
arenaTeamID)
Protected AscendStop
Stops movement initiated by JumpOrAscendStart.
Used by the JUMP binding, which also controls ascent when swimming or
flying. Has no meaningful effect if called while jumping (in which case
movement is generally stopped by hitting the ground).
Protected AssistUnit
Targets the unit targeted by another unit.
AssistUnit(“unit“) or AssistUnit(“name“)
Arguments:
unitA unit to assist (string,unitID)
nameThe name of a unit to assist (string)
Protected AttackTarget
Begins auto-attack against the player’s current target.
(If the ‘‘Auto Attack/Auto Shot’’ option is turned on, also begins Auto Shot for
hunters.)
AutoEquipCursorItem
Equips the item on the cursor.
The item is automatically equipped in the first available slot in which it fits. To
equipaniteminaspecicslot,seeEquipCursorItem().
Chapter 27 API Reference 563
Causes an error message (UI_ERROR_MESSAGE) if the item on the cursor cannot
be equipped. Does nothing if the cursor does not contain an item.
AutoLootMailItem
Automatically takes any attached items and money from a mail message.
AutoLootMailItem(mailID)
If the message does not have body text (which can be saved as a permanent
copy), also deletes the message.
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
AutoStoreGuildBankItem
Withdraws the item(s) from a slot in the guild bank, automatically adding to
the player’s bags.
AutoStoreGuildBankItem(tab, slot)
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
slotIndex of an item slot in the guild bank tab (between 1and
MAX_GUILDBANK_SLOTS_PER_TAB)(number)
BankButtonIDToInvSlotID
Returns the inventoryID corresponding to a bank item or bag slot.
inventoryID = BankButtonIDToInvSlotID(buttonID [, isBag])
Arguments:
buttonIDNumeric ID of an item or bag slot in the bank UI (number)
isBag (optional)1if the given ID corresponds to a bank bag slot; nil if the ID
corresponds to an item slot (1nil)
Returns:
inventoryIDAn inventory slot ID usable with various Inventory API func-
tions (number,inventoryID)
Example:
-- While mousing over a button in the bank
local button = GetMouseFocus()
print(“Inventory Slot:“, BankButtonIDToInvSlotID(button:GetID(),i
button.isBag))
BarberShopReset
Resets barber shop options to the currently worn styles.
Changes the underlying data (and thus the character’s appearance) only; the
default barbershop UI does not update.
Confirmation BindEnchant
Confirms enchanting an item (when the item will become soulbound as a
result).
564 Part IV Reference
Usable following the BIND_ENCHANT event which fires upon attempting to
perform an enchantment that would cause the target item to become
soulbound.
Confirmation BuyGuildBankTab
Purchases the next available guild bank tab.
BuyGuildCharter
Purchases a guild charter.
BuyGuildCharter(“guildName“)
Usable if the player is interacting with a guild registrar (i.e. between the
GUILD_REGISTRAR_SHOW and GUILD_REGISTRAR_CLOSED events).
Arguments:
guildNameName of the guild to be created (string)
Confirmation BuyMerchantItem
Purchases an item available from a vendor.
BuyMerchantItem(index, quantity)
Arguments:
indexIndex of an item in the vendor’s listing (between 1and
GetMerchantNumItems())(number)
quantityNumber of items to purchase (between 1and
GetMerchantItemMaxStack(index))(number)
BuyPetition
Purchases an arena team charter.
BuyPetition(team, “name“)
Arguments:
teamIndex of the size of team to create (number,arenaTeamID)
nameName of the team to create (string)
Confirmation BuyStableSlot
Purchases the next available stable slot, without confirmation.
Only available while interacting with a Stable Master NPC (between the
PET_STABLE_SHOW and PET_STABLE_CLOSED events and only if IsAtStable
Master() returns true).
BuyTrainerService
Purchases an ability or recipe available from a trainer.
BuyTrainerService(index)
Arguments:
indexIndex of an entry in the trainer service listing (between 1and GetNum
TrainerServices())(number)
BuybackItem
Repurchases an item recently sold to a vendor.
BuybackItem(index)
Chapter 27 API Reference 565
Arguments:
indexIndex of an item in the buyback listing (between 1and
GetNumBuybackItems())(number)
CalculateAuctionDeposit
Returns the deposit amount for the item currently being set up for auction.
deposit = CalculateAuctionDeposit(runTime)
Only returns useful information once an item has been placed in the Create
Auction UI’s ‘‘auction item’’ slot (see ClickAuctionSellItemButton()).
Deposit amount for an auction varies based on the item being auction, the
auction’s proposed run time, and the auction house being used (i.e. faction or
neutral).
Arguments:
runTimeRun time of the proposed auction (number)
720—12 hours
1440—24 hours
2880—48 hours
Returns:
depositAmount of the deposit (in copper) (number)
CalendarAddEvent
Saves the event recently created (and selected for editing) to the calendar.
Until this function is called, an event created with CalendarNewEvent(),
CalendarNewGuildEvent(),orCalendarNewGuildAnnouncement() will
not exist on the calendarthat is, guild members or invitees will not see it,
and it will not persist if the player closes the calendar, reloads the UI, or goes to
view or edit another event.
CalendarCanAddEvent
Returns whether the player can add an event to the calendar.
canAdd = CalendarCanAddEvent()
Returns:
canAddTrue if the player can add an event to the calendar; otherwise false
(boolean)
CalendarCanSendInvite
Returns whether the player can invite others to a calendar event.
canInvite = CalendarCanSendInvite()
Returns:
canInviteTrue if the player can invite others to a calendar event; otherwise
false (boolean)
CalendarCloseEvent
Deselects (ends viewing/editing on) an event.
566 Part IV Reference
After calling this function, results of attempting to query or change event
information are not guaranteed until a new event is created or another existing
event is opened.
CalendarContextDeselectEvent
Clears the event selection used only for CalendarContext functions.
The selection state cleared is used only by other CalendarContext functions;
other calendar event functions use a selection state (if needed) set by
CalendarOpenEvent,CalendarNewEvent,CalendarNewGuildEvent,or
CalendarNewGuildAnnouncement.
CalendarContextEventCanComplain
Returns whether the player can report an event invitation as spam.
canReport = CalendarContextEventCanComplain([monthOffset,] day, index)
If all arguments are omitted, uses the event selected by
CalendarContextSelectEvent.
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGetNumDay
Events())(number)
Returns:
canReporttrue if the player can report the event as spam; otherwise false
(boolean)
CalendarContextEventCanEdit
Returns whether the player can edit an event.
canEdit = CalendarContextEventCanEdit([monthOffset,] day, index)
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0The calendar’s current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
Chapter 27 API Reference 567
indexIndex of an event on the given day (from 1to CalendarGetNumDay
Events())(number)
Returns:
canEditTrue if the player can edit the event (boolean)
CalendarContextEventClipboard
Returns whether the player can paste an event.
canPaste = CalendarContextEventClipboard()
Returns:
canPastetrue if an event has been copied via CalendarContextEventCopy;
otherwise false (boolean)
CalendarContextEventComplain
Reports an event invitation as spam.
CalendarContextEventComplain([monthOffset,] day, index)
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGetNumDay
Events())(number)
CalendarContextEventCopy
Copies an event for later pasting.
CalendarContextEventCopy([monthOffset,] day, index)
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGetNumDay
Events())(number)
568 Part IV Reference
CalendarContextEventGetCalendarType
Returns the type of a calendar event.
calendarType = CalendarContextEventGetCalendarType([monthOffset,] i
day, index)
If all arguments are omitted, uses the event selected by
CalendarContextSelectEvent.
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGetNumDay
Events())(number)
Returns:
calendarTypeToken identifying the type of event (string)
GUILD_ANNOUNCEMENTGuild announcement (does not allow players to
sign up)
GUILD_EVENTGuild event (allows players to sign up)
HOLIDAYWorld event (e.g. Lunar Festival, Darkmoon Faire,
Stranglethorn Fishing Tournament, Call to Arms: Arathi Basin)
PLAYERPlayer-created event or invitation
RAID_LOCKOUTIndicates when one of the player’s saved instances resets
RAID_RESETIndicates scheduled reset times for major raid instances
SYSTEMOther server-provided event
CalendarContextEventPaste
Pastes a copied event into a given date.
CalendarContextEventPaste(monthOffset, day)
Does nothing if no event has been copied via CalendarContextEventCopy.
Arguments:
monthOffsetMonth containing an event relative to the calendar’s currently
displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
dayDay of the month (number)
Chapter 27 API Reference 569
Confirmation CalendarContextEventRemove
Deletes an event from the calendar.
CalendarContextEventRemove([monthOffset,] day, index)
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGetNumDay
Events())(number)
CalendarContextEventSignUp
Signs the player up for a guild event.
CalendarContextEventSignUp([monthOffset,] day, index)
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGetNum-
DayEvents()) (number)
CalendarContextGetEventIndex
Returns the month, day, and index of the event selection used only for
CalendarContext functions.
monthOffset, day, index = CalendarContextGetEventIndex()
The selection state referenced by this function is used only by other
CalendarContext functions; other calendar event functions use the selection
state set by CalendarOpenEvent,CalendarNewEvent,CalendarNew
GuildEvent,orCalendarNewGuildAnnouncement (if they use a selection
state at all).
Used in the default UI to implement the calendar’s context menu (on
right-click).
570 Part IV Reference
Returns:
monthOffsetMonth relative to the calendar’s currently displayed month
(number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
dayDay of the month (number)
indexIndex of the event on the given day (from 1to
CalendarGetNumDayEvents()) (number)
CalendarContextInviteAvailable
Accepts an event invitation.
CalendarContextInviteAvailable([monthOffset,] day, index)
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to
CalendarGetNumDayEvents()) (number)
CalendarContextInviteDecline
Declines an event invitation.
CalendarContextInviteDecline([monthOffset,] day, index)
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to
CalendarGetNumDayEvents()) (number)
Chapter 27 API Reference 571
CalendarContextInviteIsPending
Returns whether the player has been invited to an event and not yet
responded.
pendingInvite = CalendarContextInviteIsPending([monthOffset,] i
day, index)
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGetNum
DayEvents()) (number)
Returns:
pendingInviteTrue if the player is invited to the event and has yet to
respond; otherwise false (boolean)
CalendarContextInviteModeratorStatus
Returns the player’s moderator status for an event.
modStatus = CalendarContextInviteModeratorStatus([monthOffset,] i
day, index)
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGet
NumDayEvents()) (number)
Returns:
modStatusThe player’s level of authority for the event, or ‘‘’’ if not applicable
(number)
CREATORThe player is the original creator of the event
MODERATORThe player has been granted moderator status for the event
572 Part IV Reference
CalendarContextInviteRemove
Removes an invitation from the player’s calendar or removes the player from a
guild event’s signup list.
CalendarContextInviteRemove([monthOffset,] day, index)
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGetNum
DayEvents()) (number)
CalendarContextInviteStatus
Returns the player’s invite status for an event.
inviteStatus = CalendarContextInviteStatus([monthOffset,] day, index)
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGetNum
DayEvents()) (number)
Returns:
inviteStatusThe player’s status regarding the event (number)
1—Invited
2Accepted
3Declined
4—Conrmed
5—Out
6—Standby
7—Signed up
8—Not signed up
1is also used for non-invitation/non-signup events.
Chapter 27 API Reference 573
CalendarContextInviteType
Returns the invite type for an event.
inviteType = CalendarContextInviteType([monthOffset,] day, index)
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGetNum
DayEvents()) (number)
Returns:
inviteTypeInvitation/announcement type for the event (number)
1Characters can only be explicitly invited to the event (or event is a
non-invite/non-signup event)
2Event is visible to the player’s entire guild; guild members
can sign up and other characters can be explicitly invited
CalendarContextSelectEvent
Selects an event for use only with other CalendarContext functions.
CalendarContextSelectEvent([monthOffset,] day, index)
The selection state set by this function is used only by other CalendarContext
functions; other calendar event functions use the selection state set by
CalendarOpenEvent,CalendarNewEvent,CalendarNewGuildEvent,or
CalendarNewGuildAnnouncement (if they use a selection state at all).
Used in the default UI to implement the calendar’s context menu (on
right-click).
Arguments:
monthOffset (optional)Month containing an event relative to the calendar’s
currently displayed month (number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
nilUse the event selected by CalendarContextSelectEvent and ignore
further arguments
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGetNum
DayEvents()) (number)
574 Part IV Reference
CalendarDefaultGuildFilter
Returns default options for the guild member Mass Invite filter.
minLevel, maxLevel, rank = CalendarDefaultGuildFilter()
Returns:
minLevelLowest level of characters to invite (number)
maxLevelHighest level of characters to invite (number)
rankLowest guild rank of characters to invite (number)
CalendarEventAvailable
Accepts invitation to the selected calendar event.
Only applies to player-created events and invitations sent by other players; has
no effect if the current calendar event is of another type.
CalendarEventCanEdit
Returns whether the player can edit the selected calendar event.
canEdit = CalendarEventCanEdit()
Returns:
canEditTrue if the player can edit the current event; otherwise false
(boolean)
CalendarEventCanModerate
Returns whether an event invitee can be granted moderator authority.
canModerate = CalendarEventCanModerate(index)
Arguments:
indexIndex of a character on the event’s invite list (between 1and
CalendarEventGetNumInvites())(number)
Returns:
canModerateTrue if the given character can be given mod-
erator authority for the event; otherwise false (boolean)
CalendarEventClearAutoApprove
Disables the auto-approve feature (currently unused) for the selected calendar
event.
CalendarEventClearLocked
Unlocks the selected calendar event.
Locked events do not allow invitees to respond or guild members to sign up,
but can still be edited.
CalendarEventClearModerator
Removes moderator status from a character on the selected event’s invite/
signup list.
CalendarEventClearModerator(index)
Moderators can change the status of characters on the invite/signup list and
invite more characters, but cannot otherwise edit the event.
Chapter 27 API Reference 575
Arguments:
indexIndex of a character on the event’s invite list (between 1and Calen-
darEventGetNumInvites()) (number)
CalendarEventDecline
Declines invitation to the selected calendar event.
Only applies to player-created events and invitations sent by other players; has
no effect if the current calendar event is of another type.
CalendarEventGetCalendarType
Returns the type of the selected calendar event.
calendarType = CalendarEventGetCalendarType()
Returns:
calendarTypeToken identifying the type of event (string)
GUILD_ANNOUNCEMENTGuild announcement (does not allow players to
sign up)
GUILD_EVENTGuild event (allows players to sign up)
PLAYERPlayer-created event or invitation
CalendarEventGetInvite
Returns information about an entry in the selected event’s invite/signup list.
name, level, className, classFileName, inviteStatus, modStatus, i
inviteIsMine, inviteType = CalendarEventGetInvite(index)
Arguments:
indexIndex of a character on the event’s invite list (between 1and
CalendarEventGetNumInvites())(number)
Returns:
nameName of the character (string)
levelThe character’s current level (number)
classNameLocalized name of the character’s class (string)
classFileNameNon-localized token representing the character’s class
(string)
inviteStatusThe character’s status regarding the event (number)
1—Invited
2Accepted
3Declined
4—Conrmed
5—Out
6—Standby
7—Signed up
modStatusThe character’s level of authority for the event, or ‘‘’’ if not applica-
ble (number)
CREATORThe character is the original creator of the event
MODERATORThe character has been granted moderator status for the event
inviteIsMineTrue if this list entry represents the player; otherwise false
(boolean)
576 Part IV Reference
inviteTypeInvitation/announcement type for the event (number)
1Characters can only be explicitly invited to the event
2Event is visible to the player’s entire guild; guild members
can sign up and other characters can be explicitly invited
CalendarEventGetInviteResponseTime
Returns the time at which a character on the selected event’s invite/signup list
responded.
weekday, month, day, year, hour, minute = i
CalendarEventGetInviteResponseTime()
Returns all zeros if the character has not yet responded or is the event’s creator.
Returns:
weekdayIndex of the day of the week (starting at 1=Sunday) (number)
monthIndex of the month (starting at 1=January) (number)
dayDay of the month (number)
yearYear (full four-digit year) (number)
hourHour part of the time (on a 24-hour clock) (number)
minute—Minute part of the time (number)
CalendarEventGetInviteSortCriterion
Returns the current sort mode for the event invite/signup list.
criterion, reverse = CalendarEventGetInviteSortCriterion()
Returns:
criterionToken identifying the attribute used for sorting the list (string)
classSorted by character class (according to the global table
CLASS_SORT_ORDER)
nameSorted by character name
statusSorted by invite status
reverseTrue if the list is sorted in reverse order; otherwise false (boolean)
CalendarEventGetNumInvites
Returns the number of characters on the selected calendar event’s
invite/signup list.
numInvites = CalendarEventGetNumInvites()
Returns:
numInvitesNumber of characters on the event’s invite/signup list (number)
CalendarEventGetRepeatOptions
Returns a list of localized event repetition option labels (currently unused).
... = CalendarEventGetRepeatOptions()
Returns:
...List of localized event repetition option labels (list)
Chapter 27 API Reference 577
CalendarEventGetSelectedInvite
Returns the index of the selected entry on the selected event’s invite/signup
list.
index = CalendarEventGetSelectedInvite()
In the current default UI, selection behavior in the invite list is implemented
but disabled; selecting an invite list entry has no effect on the behavior of
other APIs.
Returns:
indexIndex of a character on the event’s invite list (between 1and Calendar
EventGetNumInvites()), or 0 if no selection has been made (number)
CalendarEventGetStatusOptions
Returns a list of localized invite status labels.
... = CalendarEventGetStatusOptions()
Returns:
...List of localized invite status labels (list)
CalendarEventGetTextures
Returns a list of instance names and icons for dungeon or raid events.
name, icon, expansion = CalendarEventGetTextures(eventType)
Arguments:
eventTypeType (display style) of event to query (number)
1—Raid dungeon
2Five-player dungeon
Returns:
nameName of an instance (may include heroic designation) (string)
iconUnique part of the path to the instance’s icon texture; for the full
path, prepend with “Interface\LFGFrame\LFGIcon-(string)
expansionExpansion to which the instance belongs; localized names can be
found in the constants EXPANSION_NAME0,EXPANSION_NAME1,etc.(number)
CalendarEventGetTypes
Returns a list of event display style labels.
... = CalendarEventGetTypes()
Returns:
...A list of localized event display style labels (list)
CalendarEventHasPendingInvite
Returns whether the player has been invited to the selected event and not yet
responded.
pendingInvite = CalendarEventHasPendingInvite()
Returns:
pendingInviteTrue if the player has been invited to the event and not yet
responded; otherwise false (boolean)
578 Part IV Reference
CalendarEventHaveSettingsChanged
Returns whether the selected event has unsaved changes.
settingsChanged = CalendarEventHaveSettingsChanged()
Returns:
settingsChangedTrue if any of the event’s attributes have been
changed since the event was last saved; otherwise false (boolean)
CalendarEventInvite
Attempts to invite a character to the selected event.
CalendarEventInvite(“name“)
If successful, the CALENDAR_UPDATE_INVITE_LIST event fires indicating the
character has been added to the invite list; otherwise the CALENDAR_UPDATE
_ERROR event fires containing a localized error message.
Arguments:
nameName of a character to invite (string)
CalendarEventIsModerator
Returns whether the player has moderator status for the selected calendar
event.
isModerator = CalendarEventIsModerator()
Also returns true if the player is the event’s creator.
Returns:
isModeratorTrue if the player has moderator status for the event; otherwise
false (boolean)
CalendarEventRemoveInvite
Removes a character from the selected event’s invite/signup list.
CalendarEventRemoveInvite(index)
Cannot be used to remove the event’s creator (fires a
CALENDAR_UPDATE_ERROR event with nil error message if such is attempted).
Arguments:
indexIndex of a character on the event’s invite list (between 1and Calendar
EventGetNumInvites()) (number)
CalendarEventSelectInvite
Selects an entry in the selected event’s invite/signup list.
CalendarEventSelectInvite(index)
In the current default UI, selection behavior in the invite list is implemented
but disabled; selecting an invite list entry has no effect on the behavior of
other APIs.
Arguments:
indexIndex of a character on the event’s invite list (between 1and Calen-
darEventGetNumInvites()) (number)
Chapter 27 API Reference 579
CalendarEventSetAutoApprove
Enables the auto-approve feature (currently unused) for the selected calendar
event.
CalendarEventSetDate
Changes the scheduled date of the selected calendar event.
CalendarEventSetDate(month, day, year)
Arguments:
monthIndex of the month (starting at 1=January) (number)
dayDay of the month (number)
yearYear (full four-digit year) (number)
CalendarEventSetDescription
Changes the descriptive text for the selected event.
CalendarEventSetDescription(“description“)
Arguments:
descriptionDescriptive text to be displayed for the event (string)
CalendarEventSetLocked
Locks the selected calendar event.
Locked events do not allow invitees to respond or guild members to sign up,
but can still be edited.
CalendarEventSetLockoutDate
Changes the lockout date associated with the selected event (currently
unused).
CalendarEventSetLockoutDate(month, day, year)
This feature is not enabled in the current version of World of Warcraft; saving
an event in which the lockout date has been changed will revert it to its default
of 1, 1, 1, 2000 (January 1, 2000).
Arguments:
monthIndex of the month (starting at 1=January) (number)
dayDay of the month (number)
yearYear (full four-digit year) (number)
CalendarEventSetLockoutTime
Changes the lockout time associated with the selected event (currently
unused).
CalendarEventSetLockoutTime(hour, minute)
This feature is not enabled in the current version of World of Warcraft; saving
an event in which the lockout time has been changed will revert it to its default
of 0, 0 (midnight).
Arguments:
hourHour part of the time (on a 24-hour clock) (number)
minute—Minute part of the time (number)
580 Part IV Reference
CalendarEventSetModerator
Grants moderator status to a character on the selected event’s invite/signup
list.
CalendarEventSetModerator(index)
Moderators can change the status of characters on the invite/signup list and
invite more characters, but cannot otherwise edit the event.
Arguments:
indexIndex of a character on the event’s invite list (between 1and Calendar
EventGetNumInvites()) (number)
CalendarEventSetRepeatOption
Changes the repetition option for the selected event (currently unused).
CalendarEventSetRepeatOption(title)
This feature is not enabled in the current version of World of Warcraft; saving
an event in which the repeat option has been changed will revert it to its
default of 1 (Never).
Arguments:
titleIndex of a repeating event option; see CalendarEventGetRepeat
Options() (number)
CalendarEventSetSize
Changes the maximum number of invites/signups for the selected event
(currently unused).
CalendarEventSetSize(size)
This feature is not enabled in the current version of World of Warcraft; saving
an event in which the max size has been changed will revert it to its default
of 100.
Arguments:
sizeMaximum number of invites/signups for the event (number)
CalendarEventSetStatus
Sets the status of a character on the selected event’s invite/signup list.
CalendarEventSetStatus(index, inviteStatus)
Arguments:
indexIndex of a character on the event’s invite list (between 1and Calendar
EventGetNumInvites()) (number)
inviteStatusThe player’s status regarding the event (number)
1—Invited
2Accepted
3Declined
4—Conrmed
5—Out
6—Standby
7—Signed up
8Not signed up (displays as ‘‘’’)
1is also used for non-invitation/non-signup events.
Chapter 27 API Reference 581
CalendarEventSetTextureID
Changes the raid or dungeon instance for the selected event.
CalendarEventSetTextureID(index)
Only applicable if the event’s eventType is set to 1 or 2 (see
CalendarEventSetType).
A list of dungeon or raid instances can be found by calling
CalendarEventGetTextures with the current eventType.Thatfunction
returns three values (name,icon,andexpansion) for each instance in the list;
e.g. to get the index for use with this function, find the index of the instance’s
name in that list and divide by 3.
Arguments:
indexIndex of a dungeon or raid instance (number)
CalendarEventSetTime
Changes the scheduled time of the selected event.
CalendarEventSetTime(hour, minute)
Arguments:
hourHour part of the time (on a 24-hour clock) (number)
minute—Minute part of the time (number)
CalendarEventSetTitle
Changes the title for the selected event.
CalendarEventSetTitle(“title“)
Arguments:
titleA title to be displayed for the event (string)
CalendarEventSetType
Changes the display type of the selected event.
CalendarEventSetType(eventType)
Arguments:
eventTypeDisplay type for the event; used in the default UI to determine
whichicontoshow(
number)
1—Raid dungeon
2Five-player dungeon
3PvP event
4Meeting
5Other event
CalendarEventSignUp
Signs the player up for the selected calendar event.
Only applies to guild events; has no effect if called when the current calendar
event is not a guild event.
582 Part IV Reference
CalendarEventSortInvites
Sorts the event invite/signup list.
CalendarEventSortInvites(“criterion“, reverse)
Does not cause the list to automatically remain sorted; e.g. if sorted by status
and a character’s status is changed, the list will not be resorted until this
function is called again.
Arguments:
criterionToken identifying the attribute to use for sorting the list (string)
classSort by character class (according to the global table
CLASS_SORT_ORDER)
nameSort by character name
statusSort by invite status
reverseTrue to sort the list in reverse order; otherwise false (boolean)
CalendarGetAbsMonth
Returns date information for a given month and year.
month, year, numDays, firstWeekday = CalendarGetAbsMonth(month, year)
Arguments:
monthIndex of a month (starting at 1=January) (number)
yearYear (full four-digit year) (number)
Returns:
monthIndex of the month (starting at 1=January) (number)
yearYear (full four-digit year) (number)
numDaysNumber of days in the month (number)
firstWeekdayIndex of the weekday (starting at 1=Sunday) for the first day
of the month (number)
CalendarGetDate
Returns the current date (in the server’s time zone).
weekday, month, day, year = CalendarGetDate()
Only returns valid information after the PLAYER_ENTERING_WORLD event has
fired.
Returns:
weekdayIndex of the day of the week (starting at 1=Sunday) (number)
monthIndex of the month (starting at 1=January) (number)
dayDay of the month (number)
yearYear (full four-digit year) (number)
CalendarGetDayEvent
Returns information about a calendar event on a given day.
title, hour, minute, calendarType, sequenceType, eventType, texture, i
modStatus, inviteStatus, invitedBy, difficulty, inviteType = i
CalendarGetDayEvent(monthOffset, day, index)
Chapter 27 API Reference 583
Information can only be retrieved for events which might be visible in the
calendar’s current monthi.e. those in the current month as well as those in
(roughly) the last week of the previous month and (roughly) the first two
weeks of the following month. To reliably retrieve information for events
outside the calendar’s current month, first change the calendar’s month with
CalendarSetMonth.
Arguments:
monthOffsetMonth containing an event relative to the calendar’s currently
displayed month (number)
-1Month preceding the calendar’s current month
0The calendar’s current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
dayDay of the month containing an event (number)
indexIndex of an event on the given day (from 1to CalendarGetNum-
DayEvents()) (number)
Returns:
titleTitle displayed for the event (string)
hourHour part of the event’s start time (on a 24-hour clock) (number)
minuteMinute part of the event’s start time (number)
calendarTypeToken identifying the type of event (string)
GUILD_ANNOUNCEMENTGuild announcement (does not allow players to
sign up)
GUILD_EVENTGuild event (allows players to sign up)
HOLIDAYWorld event (e.g. Lunar Festival, Darkmoon Faire,
Stranglethorn Fishing Tournament, Call to Arms: Arathi Basin)
PLAYERPlayer-created event or invitation
RAID_LOCKOUTIndicates when one of the player’s saved instances resets
RAID_RESETIndicates scheduled reset times for major raid instances
SYSTEMOther server-provided event
sequenceTypeDisplay cue for multi-day events, or ‘‘’’ if not applicable
(string)
ENDLast day of the event
INFOAn additional specially-labeled day related the event
ONGOINGContinuation of the event
STARTFirst day of the event
eventTypeDisplay type for the event; used in the default UI to determine
whichicontoshow(
number)
0Holiday or other server-provided
event
1—Raid dungeon
2Five-player dungeon
3PvP event
4Meeting
5Other event
584 Part IV Reference
textureUnique portion of the path to a texture for the event (e.g. ‘‘Cal-
endar_ChildrensWeek’’). The mechanism by which a full texture path can
be generated is not public API, but can be found in Addons/Blizzard_Calendar
/Blizzard_Calendar.lua after extracting default UI files with the AddOn Kit.
(string)
modStatusThe player’s level of authority for the event, or ‘‘’’ if not applicable
(number)
CREATORThe player is the original creator of the event
MODERATORThe player has been granted moderator status for the event
inviteStatusThe player’s status regarding the event (number)
1—Invited
2Accepted
3Declined
4—Conrmed
5—Out
6—Standby
7—Signed up
8—Not signed up
1is also used for non-invitation/non-signup events.
invitedByName of the character who created (or invited the player to) the
event (string)
difficultyDifficulty of the dungeon or raid instance associ-
ated with the event (used only for RAID_LOCKOUT and RAID_RESET
events, not player-created raid/dungeon events) (number)
1—Normal
2—Heroic
inviteTypeInvitation/announcement type for the event (number)
1Characters can only be explicitly invited to the event (or event is a
non-invite/non-signup event)
2Event is visible to the player’s entire guild; guild members
can sign up and other characters can be explicitly invited
CalendarGetEventIndex
Returns the month, day, and index of the selected calendar event.
monthOffset, day, index = CalendarGetEventIndex()
Returns:
monthOffsetMonth relative to the calendar’s currently displayed month
(number)
-1Month preceding the calendar’s current month
0Current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
dayDay of the month (number)
indexIndex of the event on the given day (from 1to CalendarGetNum
DayEvents()) (number)
Chapter 27 API Reference 585
CalendarGetEventInfo
Returns information about the selected calendar event (for player/guild
events).
title, description, creator, eventType, repeatOption, maxSize, i
textureIndex, weekday, month, day, year, hour, minute, i
lockoutWeekday, lockoutMonth, lockoutDay, lockoutYear, lockoutHour, i
lockoutMinute, locked, autoApprove, pendingInvite, inviteStatus, i
inviteType, calendarType = CalendarGetEventInfo()
Returns:
titleTitle displayed for the event (string)
descriptionDescriptive text about the event (string)
creatorName of the character who created the event (string)
eventTypeDisplay style for the event; used in the default UI to determine
whichicontoshow(
number)
1—Raid dungeon
2Five-player dungeon
3PvP event
4Meeting
5Other event
repeatOptionIndex of an event repetition option (see Calen-
darEventGetRepeatOptions); currently unused (always 1) (number)
maxSizeMaximum number of invites/signups; currently unused (always 100)
(number)
textureIndexIndex of the dungeon or raid instance (between 1and
select(“#“, CalendarEventGetTextures(eventType)) / 3 (number)
weekdayIndex of the day of the week on which the event starts (starting at 1=
Sunday) (number)
monthIndex of the month in which the event starts (starting at 1=January)
(number)
dayDay of the month on which the event starts (number)
yearYear in which the event starts (full four-digit year) (number)
hourHour part of the event’s start time (on a 24-hour clock) (number)
minuteMinute part of the event’s start time (number)
lockoutWeekdayCurrently unused (number)
lockoutMonthCurrently unused (number)
lockoutDayCurrently unused (number)
lockoutYearCurrently unused (number)
lockoutHourCurrently unused (number)
lockoutMinuteCurrently unused (number)
locked1if the event is locked (preventing invitees from responding); other-
wise nil (1nil)
autoApprove1if signups to the event should be automatically approved (cur-
rently unused); otherwise nil (1nil)
586 Part IV Reference
pendingInvite1if the player has been invited to this event and has not yet
responded; otherwise nil (1nil)
inviteStatusThe player’s status regarding the event (number)
1—Invited
2Accepted
3Declined
4—Conrmed
5—Out
6—Standby
7—Signed up
8—Not signed up
inviteTypeInvitation/announcement type for the event (number)
1Player has been explicitly invited to the event and can accept or decline
2Event is visible to the player’s entire guild; player can sign up if desired
calendarTypeToken identifying the type of event (string)
GUILD_ANNOUNCEMENTGuild announcement (does not allow players to sign
up)
GUILD_EVENTGuild event (allows players to sign up)
PLAYERPlayer-created event or invitation
SYSTEMOther server-provided event
CalendarGetFirstPendingInvite
Returns the index of the first invitation on a given day to which the player has
not responded.
index = CalendarGetFirstPendingInvite(monthOffset, day)
Arguments:
monthOffsetMonth to query relative to the calendar’s currently dis-
played month (i.e. 0 for current month, 1for next month, -1 for previous month)
(number)
dayDay of the month to query (number)
Returns:
indexIndex of the event on the given day (from 1to CalendarGetNum-
DayEvents()) (number)
CalendarGetHolidayInfo
Returns additional information about a holiday event.
name, description, texture = i
CalendarGetHolidayInfo(monthOffset, day, index)
Information can only be retrieved for events which might be visible in the
calendar’s current monthi.e. those in the current month as well as those in
(roughly) the last week of the previous month and (roughly) the first two
weeks of the following month. To reliably retrieve information for events
outside the calendar’s current month, first change the calendar’s month with
CalendarSetMonth.
Arguments:
monthOffsetMonth to query relative to the calendar’s currently dis-
played month (i.e. 0 for current month, 1for next month, -1 for previous month)
(number)
Chapter 27 API Reference 587
dayDay of the month to query (number)
indexIndex of an event on the given day (from 1to CalendarGetNum
DayEvents()) (number)
Returns:
nameLocalized name of the event (string)
descriptionLocalized text describing the event (string)
textureUnique portion of the path to a texture for the event (e.g. ‘‘Cal-
endar_ChildrensWeek’’). The mechanism by which a full texture path can be
generated is not public API, but can be found in Addons/Blizzard_Calendar
/Blizzard_Calendar.lua after extracting default UI files with the AddOn Kit.
(string)
CalendarGetMaxCreateDate
Returns the latest date for which events may be scheduled.
weekday, month, day, year = CalendarGetMaxCreateDate()
Currently, events can only be created up to one year from the last day of the
current month (e.g. if the current date is May 19, 2009, the player is not allowed
to create events scheduled for later than May 31, 2010). The default Calendar
UI also does not allow viewing months beyond this date.
Returns:
weekdayIndex of the day of the week (starting at 1=Sunday) (number)
monthIndex of the month (starting at 1=January) (number)
dayDay of the month (number)
yearYear (full four-digit year) (number)
CalendarGetMaxDate
Returns the latest date usable in the calendar system.
weekday, month, day, year = CalendarGetMaxDate()
This function currently always returns December 31st, 2030 as the max date.
Returns:
weekdayIndex of the day of the week (starting at 1=Sunday) (number)
monthIndex of the month (starting at 1=January) (number)
dayDay of the month (number)
yearYear (full four-digit year) (number)
CalendarGetMinDate
Returns the earliest date usable in the calendar system.
weekday, month, day, year = CalendarGetMinDate()
This function currently returns November 24th, 2004 as the minimum date.
This is the date that World of Warcraft was launched in the U.S.
Returns:
weekdayIndex of the day of the week (starting at 1=Sunday) (number)
monthIndex of the month (starting at 1=January) (number)
588 Part IV Reference
dayDay of the month (number)
yearYear (full four-digit year) (number)
CalendarGetMinHistoryDate
Returns the earliest date for which information about past player events is
available.
weekday, month, day, year = CalendarGetMinHistoryDate()
Applies to events created by the player, invites the player accepted, and guild
events or announcements. Currently, the default UI only shows past events
from up to two weeks before the current date.
Returns:
weekdayIndex of the day of the week (starting at 1=Sunday) (number)
monthIndex of the month (starting at 1=January) (number)
dayDay of the month (number)
yearYear (full four-digit year) (number)
CalendarGetMonth
Returns information about a calendar month.
month, year, numDays, firstWeekday = CalendarGetMonth([monthOffset])
Arguments:
monthOffset (optional)Month to query relative to the calendar’s currently
displayed month (i.e. 0 for current month, 1for next month, -1 for previous
month). Defaults to the calendar’s current month if omitted. (number)
Returns:
monthIndex of the month (starting at 1=January) (number)
yearYear (full four-digit year) (number)
numDaysNumber of days in the month (number)
firstWeekdayIndex of the weekday (starting at 1=Sunday) for the first day
of the month (number)
CalendarGetMonthNames
Returns a list of localized month names.
... = CalendarGetMonthNames()
Returns:
...A list of localized month names in calendar order (i.e. 1=January) (list)
CalendarGetNumDayEvents
Returns the number of calendar events on a given day.
numEvents = CalendarGetNumDayEvents(monthOffset, day)
Arguments:
monthOffsetMonth to query relative to the calendar’s currently displayed
month (i.e. 0for current month, 1for next month, -1 for previous month)
(number)
dayDay of the month to query (number)
Chapter 27 API Reference 589
Returns:
numEventsNumber of events on the given day (number)
CalendarGetNumPendingInvites
Returns the number of calendar invitations to which the player has yet to
respond.
numInvites = CalendarGetNumPendingInvites()
Returns:
numInvitesNumber of pending calendar invitations (number)
CalendarGetRaidInfo
Returns information about a raid lockout or scheduled raid reset event.
title, calendarType, raidID, hour, minute, difficulty = i
CalendarGetRaidInfo(monthOffset, day, index)
Information can only be retrieved for events which might be visible in the
calendar’s current monthi.e. those in the current month as well as those in
(roughly) the last week of the previous month and (roughly) the first two
weeks of the following month. To reliably retrieve information for events
outside the calendar’s current month, first change the calendar’s month with
CalendarSetMonth.
Arguments:
monthOffsetMonth to query relative to the calendar’s currently dis-
played month (i.e. 0 for current month, 1for next month, -1 for previous month)
(number)
dayDay of the month to query (number)
indexIndex of an event on the given day (from 1to CalendarGetNum
DayEvents()) (number)
Returns:
titleTitle displayed for the event (number)
calendarTypeToken identifying the type of event (string)
RAID_LOCKOUTIndicates when one of the player’s saved instances resets
RAID_RESETIndicates scheduled reset times for major raid instances
raidIDID number of the instance to which the player is saved, or 0 if not
applicable (number)
hourHour part of the time at which the instance resets (on a 24-hour clock)
(number)
minuteMinute part of the time at which the instance resets (number)
difficultyDifficulty of the dungeon or raid instance associated with the
event (number)
1—Normal
2—Heroic
CalendarGetWeekdayNames
Returns a list of localized weekday names.
... = CalendarGetWeekdayNames()
590 Part IV Reference
Returns:
...A list of localized weekday names in calendar order (i.e. 1=Sunday)
(list)
CalendarIsActionPending
Returns whether an update to calendar information is in progress.
isPending = CalendarIsActionPending()
Returns true while the client is synchronizing its calendar information from the
server; e.g. after calling CalendarOpenEvent, CalendarAddEvent, or Calendar
UpdateEvent. During such periods, using other calendar API functions to
query or change event information may not have valid or expected results.
Returns:
isPendingTrue if an update to calendar information is in progress; otherwise
false (boolean)
CalendarMassInviteArenaTeam
Repopulates the current event’s invite list with members of one of the player’s
arena teams.
CalendarMassInviteArenaTeam(index)
Clears any invites already listed. Can only be used for events not yet created
(i.e. saved to the calendar).
Arguments:
indexIndex of an arena team type (number)
1—2v2 team
2—3v3 team
3—5v5 team
CalendarMassInviteGuild
Repopulates the selected event’s invite list with members of the player’s guild.
CalendarMassInviteGuild(minLevel, maxLevel, rank)
Clears any invites already listed. Can only be used for events not yet created
(i.e. saved to the calendar).
Arguments:
minLevelLowest level of characters to invite (number)
maxLevelHighest level of characters to invite (number)
rankLowest guild rank of characters to invite (number)
CalendarNewEvent
Creates a new event and selects it for viewing/editing.
CalendarNewGuildAnnouncement
Creates a new guild announcement and selects it for viewing/editing.
Guild announcements are visible to all guild members but do not allow
signups or invitations.
Chapter 27 API Reference 591
CalendarNewGuildEvent
Creates a new guild event and selects it for viewing/editing.
Guild events are visible to all guild members and allow members to sign up (or
non-members to be invited).
CalendarOpenEvent
Selects a calendar event for viewing/editing.
CalendarOpenEvent(monthOffset, day, index)
Arguments:
monthOffsetMonth to query relative to the calendar’s currently dis-
played month (i.e. 0 for current month, 1for next month, -1 for previous month)
(number)
dayDay of the month to query (number)
indexIndex of an event on the given day (from 1to CalendarGetNum
DayEvents()) (number)
CalendarRemoveEvent
Removes the selected event invitation from the player’s calendar or removes
the player from the selected guild event’s signup list.
NOTE: May disconnect the player if called when the selected calendar event is
not a received invitation or a guild event.
CalendarSetAbsMonth
Set’s the calendar’s month to an absolute date.
CalendarSetAbsMonth(month [, year])
Arguments:
monthIndex of the month (starting at 1=January) (number)
year (optional)Year (full four-digit year); uses current year if omitted
(number)
CalendarSetMonth
Sets the calendar’s month relative to its current month.
CalendarSetMonth(monthOffset)
Arguments:
monthOffsetMonth containing an event relative to the calendar’s currently
displayed month (number)
-1Month preceding the calendar’s current month
0The calendar’s current month (i.e. same month as CalendarGetMonth())
1Month after the calendar’s current month
CalendarUpdateEvent
Saves changes made to the selected event.
Until this function is called, changes made to an event will not be savedthey
will not propagate to guild members or invitees, and the event will revert to its
previous state if the player closes the calendar, reloads the UI, or goes to view
or edit another event.
592 Part IV Reference
Only applies to existing events; for newly created events use CalendarAdd
Event() once the event’s attributes and initial invite list are set.
CallCompanion
Summons a non-combat pet or mount.
CallCompanion(“type“, index)
If called referencing the current non-combat pet, dismisses it. Does nothing if
givenanindexgreaterthanGetNumCompanions(type).
Arguments:
typeType of companion (string)
CRITTERA non-combat pet
MOUNT—A mount
indexIndex of a companion (between 1and GetNumCompanions(type))
(number)
Protected CameraOrSelectOrMoveStart
Begins camera movement or selection (equivalent to left-clicking in the 3-D
world).
After calling this function (i.e. while the left mouse button is held), cursor
movement rotates the camera. Final results vary by context and are determined
when calling CameraOrSelectOrMoveStop() (i.e. releasing the left mouse
button).
Used by the CAMERAORSELECTORMOVE binding (not customizable in the default
UI), which is bound to the left mouse button by default.
Protected CameraOrSelectOrMoveStop
Ends action initiated by CameraOrSelectOrMoveStart.
CameraOrSelectOrMoveStop(isSticky)
After calling this function (i.e. releasing the left mouse button), camera
movement stops and normal cursor movement resumes. If the cursor has not
moved significantly since calling CameraOrSelectOrMoveStart()
(i.e. pressing the left mouse button) and is over a unit, that unit becomes the
player’s target; if the cursor has not moved significantly and is not over a unit,
clears the player’s target unless the ‘‘Sticky Targeting’’ option is enabled
(i.e. the ‘‘deselectOnClick’’ CVar is 0).
Used by the CAMERAORSELECTORMOVE binding (not customizable in the default
UI), which is bound to the left mouse button by default.
Arguments:
isStickyIf 1, the camera will remain static until cancelled. Otherwise,
the camera will pan back to be directly behind the character (1nil)
CameraZoomIn
Zooms the camera in by a specified distance.
CameraZoomIn(distance)
Chapter 27 API Reference 593
The max distance of the camera is set in the Interface Options screen, and the
maximum distance allowed is enforced by this setting, and the game client.
Depending on the setting, this is between 15.0 and 24.0 in the current version of
the client.
Arguments:
distanceThe distance to zoom in (number)
CameraZoomOut
Zooms the camera out by a specified distance.
CameraZoomOut(distance)
This function is used to zoom the camera out. The max distance of the camera
is set in the Interface Options screen, and the maximum distance allowed is
enforced by this setting, and the game client. Depending on the setting, this is
between 15.0 and 24.0 in the current version of the client.
Arguments:
distanceThe distance to zoom out (number)
CanAlterSkin
Lets you check if the player can change their skin color.
canAlter = CanAlterSkin()
Returns true if the player can change their skin color while using the
barbershop.
Returns:
canAlterCan the player change skin color (boolean)
CanCancelAuction
Returns whether one of the player’s auctions can be canceled.
canCancel = CanCancelAuction(index)
Generally, non-cancelable auctions are those which have completed but for
which payment has not yet been delivered.
Arguments:
indexIndex of an auction in the ‘‘owner’’ listing (number)
Returns:
canCancel1if the auction can be canceled; otherwise nil (1nil)
CanComplainChat
Returns whether a chat message can be reported as spam.
canComplain = CanComplainChat(lineID)
Arguments:
lineIDUnique identifier of a chat message (11th argument received with the
corresponding CHAT_MSG event) (number)
Returns:
canComplain1if the player can report the given chat message as spam; other-
wise nil (1nil)
594 Part IV Reference
CanComplainInboxItem
Returns whether a mail message can be reported as spam.
complain = CanComplainInboxItem(mailID)
Returns nil for messages from Game Masters or friends, as well as for messages
generated by the game itself (Auction House mail, quest messages from NPCs,
etc).
As with most mail functions, only provides valid information if used while the
mail UI is open (between the MAIL_SHOW and MAIL_CLOSE events).
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
Returns:
complain1if the inbox item can be reported as spam; otherwise nil (1nil)
CanEditGuildEvent
Returns whether the player is allowed to edit guild-wide calendar events.
canEdit = CanEditGuildEvent()
Returns:
canEdit1if the player can create or edit guild calendar events, otherwise nil
(1nil)
CanEditGuildInfo
Returns whether the player is allowed to edit the guild information text.
canEdit = CanEditGuildInfo()
This text appears when clicking the ‘‘Guild Information’’ button in the default
UI’s Guild window.
Returns:
canEdit1if the player can edit the guild information; otherwise nil (1nil)
CanEditGuildTabInfo
Returns whether the player is allowed to edit a guild bank tab’s iinformation.
canEdit = CanEditGuildTabInfo(tab)
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
Returns:
canEdit1if the player can edit the guild bank tab; otherwise nil (1nil)
CanEditMOTD
Returns whether the player is allowed to edit the guild Message of the Day.
canEdit = CanEditMOTD()
Returns:
canEdit1if the player can edit the guild MOTD, otherwise nil (1nil)
Chapter 27 API Reference 595
CanEditOfficerNote
Returns whether the player is allowed to edit guild officer notes.
canEdit = CanEditOfficerNote()
Returns:
canEdit1if the player can edit officer notes; otherwise nil (1nil)
CanEditPublicNote
Returns whether the player is allowed to edit guild public notes.
canEdit = CanEditPublicNote()
Returns:
canEdit1if the player can edit public notes, otherwise nil (1nil)
CanEjectPassengerFromSeat
Returns whether the player can eject the occupant of a seat in the player’s
vehicle.
canEject = CanEjectPassengerFromSeat(seat)
Arguments:
seatIndex of a seat in the player’s vehicle (number)
Returns:
canEjectTrue if the player can eject the seat’s occupant; false if the
player cannot eject the occupant or if the seat is empty (boolean)
CanExitVehicle
Returns whether the player is in a vehicle.
canExit = CanExitVehicle()
Used in the default UI to determine whether to show the ‘‘Leave Vehicle’’
button while controlling siege vehicles, turrets, and certain special mounts and
quest entities.
Returns:
canExit1if the player is in a vehicle and can exit; otherwise nil (1nil)
CanGrantLevel
Returns whether the player can give levels to a Recruit-a-Friend partner.
canGrant = CanGrantLevel(“unit“)
Arguments:
unitUnit to gift a level (string,unitID)
Returns:
canGrant1if the player can grant a level to the unit; otherwise nil (1nil)
CanGuildBankRepair
Returns whether the player is allowed to pay for repairs using guild bank
funds.
canRepair = CanGuildBankRepair()
Returns:
canRepair1if the player can use guild bank funds for repair; otherwise nil
(1nil)
596 Part IV Reference
CanGuildDemote
Returns whether the player is allowed to demote lower ranked guild members.
canDemote = CanGuildDemote()
Returns:
canDemote1if the player can demote lower ranked guild members; otherwise
nil (1nil)
CanGuildInvite
Returns whether the player is allowed to invite new members to his or her
guild.
canInvite = CanGuildInvite()
Returns:
canInvite1if the player can invite members to their guild, otherwise nil
(1nil)
CanGuildPromote
Returns whether the player is allowed to promote other guild members.
canPromote = CanGuildPromote()
The player may promote other members only up to the rank below his or her
own.
Returns:
canPromote1if the player can promote other guild members; otherwise nil
(1nil)
CanGuildRemove
Returns whether the player is allowed to remove members from his or her
guild.
canRemove = CanGuildRemove()
The player may only remove lower ranked members from the guild.
Returns:
canRemove1if the player can remove a member from their guild, otherwise
nil (1nil)
CanHearthAndResurrectFromArea
Returns whether the player is in a world PvP zone offering an exit option.
status = CanHearthAndResurrectFromArea()
Used by the default UI to show the MiniMapBattlefieldFrame and provide a
menu option for leaving if the player is in a world PvP combat zone
(i.e. Wintergrasp).
Returns:
status1if in a world PvP zone with an exit option; otherwise nil (1nil)
CanInspect
Returns whether a unit can be inspected.
canInspect = CanInspect(“unit“, showError)
Chapter 27 API Reference 597
Returns nil if the unit is out of inspect range, if the unit is an NPC, or if the
unit is flagged for PvP combat and hostile to the player.
Arguments:
unitA unit to inspect (string,unitID)
showErrorTrue to fire a UI_ERROR_MESSAGE event (causing the default UI
to display an error message) if the unit cannot be inspected; otherwise false
(boolean)
Returns:
canInspect1if the unit can be inspected; otherwise nil (1nil)
CanJoinBattlefieldAsGroup
Returns whether the battleground for which the player is queueing supports
joining as a group.
canGroupJoin = CanJoinBattlefieldAsGroup()
Returns:
canGroupJoin1if the currently displayed battlefield supports joining as a
group (1nil)
CanMerchantRepair
Returns whether the vendor with whom the player is currently interacting can
repair equipment.
canRepair = CanMerchantRepair()
Returns:
canRepair1if the vendor can repair equipment; otherwise nil (1nil)
CanQueueForWintergrasp
Returns whether the player can queue for Wintergrasp.
canQueue = CanQueueForWintergrasp()
Returns:
canQueueCan the player queue for Wintergrasp (boolean)
CanSendAuctionQuery
Returns whether the player can perform an auction house query.
canQuery, canMassQuery = CanSendAuctionQuery(“list“)
All auction query types are throttled, preventing abuse of the server by clients
sending too many queries in short succession. Normal queries can be sent
once every few seconds; mass queries return all results in the auction house
instead of one ‘‘page’’ at a time, and can only be sent once every several
minutes.
Arguments:
listType of auction listing (string)
bidderAuctions the player has bid on
listAuctions the player can browse and bid on or buy out
ownerAuctions the player placed
598 Part IV Reference
Returns:
canQuery1if the player can submit an auction query; otherwise nil (1nil)
canMassQuery1if the player can submit a mass auction query; otherwise nil
(1nil)
CanSendLFGQuery
Returns whether the player can perform a given LFM query.
canSend = CanSendLFGQuery(type, index)
LFM requests are throttled, preventing abuse of the server by clients sending
too many queries in short succession. The server may block repeat requests for
the same query parameters while allowing requests with different
parameterschecking this function before calling LFGQuery() verifies
whether the specific query parameters are currently allowed.
Arguments:
typeIndex of an LFG query type (in the list returned by GetLFGTypes())
(number)
indexIndex of an LFG entry (in the list returned by GetLFGTypeEntries
(type))(number)
Returns:
canSendtrue if the player can submit a LFG query for the given type/index,
otherwise false (boolean)
CanShowAchievementUI
Returns whether the Achievements UI should be enabled.
canShow = CanShowAchievementUI()
Used by the default UI to determine whether to show or hide the menu button
for Achievements (as it also does for Talents); currently always returns true.
Returns:
canShowtrue if the Achievements UI should be enabled, otherwise false
(boolean)
CanShowResetInstances
Returns whether the player can reset instances.
canResetInstances = CanShowResetInstances()
Used to determine whether to display the ‘‘Reset Instance’’ option in the unit
popup menu for the player.
Only instances to which the player is not saved may be reset (i.e. normal 5-man
dungeons, not heroic dungeons or raids), and only by a solo player or group
leader.
Returns:
canResetInstances1if the player can currently reset instances; otherwise
nil (1nil)
Chapter 27 API Reference 599
CanSignPetition
Returns whether the player can sign the currently offered petition.
canSign = CanSignPetition()
Petitions can only be signed once per account, rather than once per character.
Returns:
canSign1if the player can sign the offered petition; otherwise nil (1nil)
CanSummonFriend
Returns whether a unit can be summoned via Recruit-a-Friend.
canSummon = CanSummonFriend(“name“) or CanSummonFriend(“unit“)
Indicates whether the target unit is currently summonable, not just whether
that unit’s account is linked to the player’s via the Recruit-A-Friend program.
Arguments:
nameExact name of a player to summon (string)
unitA unit to summon (string,unitID)
Returns:
canSummon1if the unit can be summoned, otherwise nil (1nil)
CanSwitchVehicleSeat
Returns whether the player can change vehicle seats.
canSwitch = CanSwitchVehicleSeat()
Tells you if the player can switch seats in general, whereas
UnitVehicleSeatInfo() tells you if the player can switch into a specific seat.
Returns:
canSwitchCan the player change vehicle seats (boolean)
Example:
local controlType, occupantName, occupantRealm, canEject, i
canSwitchSeats = UnitVehicleSeatInfo(“player“, 1)
if( CanSwitchVehicleSeat() and canSwitchSeats ) then
print(“You can switch to seat #1!“)
end
CanSwitchVehicleSeats
Returns whether the player is in a vehicle with multiple seats.
canSwitch = CanSwitchVehicleSeats()
Returns:
canSwitch1if the player can switch seats; otherwise nil (1nil)
CanUseEquipmentSets
Returns whether the player has enabled the equipment manager.
enabled = CanUseEquipmentSets()
Despite the name, this returns true when the player has enabled the use of the
equipment manager through the interface or CVars.
600 Part IV Reference
Returns:
enabledHas the player enable the equipment manager (boolean)
CanViewOfficerNote
Returns whether the player is allowed to view guild officer notes.
canView = CanViewOfficerNote()
Returns:
canView1if the player can view officer notes, otherwise nil (1nil)
CanWithdrawGuildBankMoney
Returns whether the player is allowed to withdraw money from the guild
bank.
canWithdraw = CanWithdrawGuildBankMoney()
Returns:
canWithdraw1if the player can withdraw money from the guild bank; other-
wise nil (1nil)
CancelAreaSpiritHeal
Declines the next upcoming periodic resurrection from a battleground spirit
healer.
Usable in response to the AREA_SPIRIT_HEALER_IN_RANGE event which fires
when the player’s ghost is near a battleground spirit healer.
Confirmation CancelAuction
Cancels an auction created by the player.
CancelAuction(index)
When canceling an auction, the deposit amount is not refunded.
Arguments:
indexIndex of an auction in the ‘‘owner’’ listing (number)
CancelBarberShop
Exits a barber shop session.
Causes the player character to stand up, returning to the normal world, and
fires the BARBER_SHOP_CLOSE event. Any style changes already paid for (with
ApplyBarberShopStyle()) are kept; any changes since are discarded.
CancelDuel
Cancels a proposed duel, or declines an offered duel.
CancelItemTempEnchantment
Cancels a temporary weapon enchant.
CancelItemTempEnchantment(slot)
Examples of temporary enchants include mana oils, sharpening stones, and
Shaman weapon enhancements.
Arguments:
slot1to cancel the mainhand item enchant, 2 to cancel the offhand item
enchant (number)
Chapter 27 API Reference 601
CancelLogout
Cancels a pending logout or quit.
Only has effect if logout or quit is pending (following the PLAYER_CAMPING or
PLAYER_QUITING event).
CancelPendingEquip
Cancels equipping a bind-on-equip item.
CancelPendingEquip(index)
When the player attempts to equip a bind-on-equip item, the default UI
displays a dialog warning that equipping the item will cause it to become
soulbound; this function is called when canceling that dialog.
Arguments:
indexIndex of a pending equip warning; currently always 0
as only one equip warning will be given at a time (number)
CancelPendingLFG
Cancels active LFG searches, removing the player from the LFG queue and
declining any automatic group invitations.
CancelShapeshiftForm
Cancels the current shapeshift form.
Unlike other Shapeshift APIs, this function refers specifically to shapeshifting;
therefore including some abilities not found on the default UI’s ShapeshiftBar
and excluding some which are. For example, cancels shaman Ghost Wolf form
and druid shapeshifts but not warrior stances, paladin auras, or rogue stealth.
CancelSummon
Declines an offered summons.
Usable between when the CONFIRM_SUMMON event fires (due to a summoning
spell cast by another player) and when the value returned by
GetSummonConfirmTimeLeft() reaches zero.
CancelTrade
Cancels a trade in progress.
Can be used if either party has accepted the trade, but not once both have.
CancelTradeAccept
Cancels the player’s acceptance of a trade.
If the player has accepted the trade but the target has not, reverts the player to
the pre-acceptance state but does not end the trade.
CancelUnitBuff
Cancels a buff on the player.
CancelUnitBuff(“unit“, index [, “filter“]) or i
CancelUnitBuff(“unit“, “name“ [, “rank“ [, “filter“]])
Arguments:
unitA unit to query (only valid for ‘player’) (string,unitID)
indexIndex of an aura to query (number)
602 Part IV Reference
nameName of an aura to query (string)
rank (optional)Secondary text of an aura to query (often a rank; e.g. ‘‘Rank 7’’)
(string)
filter (optional)A list of filters to use separated by the pipe ‘|’character;
e.g. “RAID|PLAYER“ will query group buffs cast by the player (string)
CANCELABLEQuery auras that can be cancelled
HARMFUL—Query debuffs only
HELPFUL—Query buffs only
NOT_CANCELABLEQuery auras that cannot be cancelled
PLAYERQuery auras the player has cast
RAIDQuery auras the player can cast on party/raid members (as opposed
to self buffs)
Protected CastPetAction
Casts a pet action on a specific target.
CastPetAction(index [, “unit“])
Arguments:
indexIndex of a pet action button (between 1and NUM_PET_ACTION_SLOTS)
(number)
unit (optional)A unit to be used as target for the action (string,unitID)
Protected CastShapeshiftForm
Casts an ability on the stance/shapeshift bar.
CastShapeshiftForm(index)
Arguments:
indexIndex of an ability on the stance/shapeshift bar (between 1and
GetNumShapeshiftForms())(number)
Protected CastSpell
Casts a spell from the spellbook.
CastSpell(id, “bookType“)
Only protected (i.e. usable only by the Blizzard UI) if the given id corresponds
to a spell which can be cast (not a passive spell) and is not a trade skill; can be
used by addons to cast the ‘‘spells’’ that open trade skill windows.
Arguments:
idIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
Protected CastSpellByID
Casts a spell specified by id (optionally on a specified unit).
CastSpellByID(spellID [, “target“])
Chapter 27 API Reference 603
Only protected (i.e. usable only by the Blizzard UI) if the given spell is castable
(not passive) and is not a trade skill; can be used by addons to cast the ‘‘spells’’
that open trade skill windows.
Arguments:
spellIDID of the spell to cast (number, spellID)
target (optional)A unit to target with the spell (string,unitID)
Protected CastSpellByName
Casts a spell specified by name (optionally on a specified unit).
CastSpellByName(“name“ [, “target“])
Only protected (i.e. usable only by the Blizzard UI) if the given spell is castable
(not passive) and is not a trade skill; can be used by addons to cast the ‘‘spells’’
that open trade skill windows.
Arguments:
nameName of a spell to cast (string)
target (optional)A unit to target with the spell (string,unitID)
No Combat ChangeActionBarPage
Changes the current action bar page.
ChangeActionBarPage(page)
Arguments:
pageThe action bar page to change to (number)
ChangeChatColor
Changes the color associated with a chat message type.
ChangeChatColor(“messageGroup“, red, green, blue)
Arguments:
messageGroupToken identifying a message type (string, chatMsgType)
redRedcomponentofthecolorvalue(0.0-1.0)(number)
greenRed component of the color value (0.0 - 1.0) (number)
blueRedcomponentofthecolorvalue(0.0-1.0)(number)
ChannelBan
Bans a character from a chat channel.
ChannelBan(“channel“, “fullname“)
Has no effect unless the player is a moderator of the given channel
Arguments:
channelName of the channel (string)
fullnameName of the character to be banned (string)
ChannelInvite
Invites a character to join a chat channel.
ChannelInvite(“channel“, “name“)
604 Part IV Reference
Arguments:
channelName of a channel (string)
nameName of a character to invite (string)
ChannelKick
Removes a player from the channel.
ChannelKick(“channel“, “fullname“)
Has no effect unless the player is a moderator of the given channel
Arguments:
channelName of the channel (string)
fullnameName of the character to kick (string)
ChannelModerator
Grants a character moderator status in a chat channel.
ChannelModerator(“channel“, “fullname“)
Has no effect unless the player is the owner of the given channel
Arguments:
channelName of the channel (string)
fullnameName of the character to promote to moderator (string)
ChannelMute
Grants a character ability to speak in a moderated chat channel.
ChannelMute(“channelName“, “name“) or ChannelMute(channelId, “name“)
Arguments:
channelNameName of a channel (string)
channelIdIndex of a channel (number)
nameName of a character to mute (string)
ChannelSilenceAll
Silences a character for chat and voice on a channel.
ChannelSilenceAll(“channelName“, [“unit“] or [“name“]) or
ChannelSilenceAll(channelId, [“unit“] or [“name“]) or
ChannelSilenceAll([“channelName“] or [channelId], “unit“) or
ChannelSilenceAll([“channelName“] or [channelId], “name“)
Arguments:
channelNameName of a channel (string)
channelIdIndex of a channel (number)
unitUnit to silence (string,unitID)
nameName of a character to silence (string)
ChannelSilenceVoice
Silences the given character for voice chat on the channel.
ChannelSilenceVoice(“channelName“, [“unit“] or [“name“]) or
ChannelSilenceVoice(channelId, [“unit“] or [“name“]) or
Chapter 27 API Reference 605
ChannelSilenceVoice([“channelName“] or [channelId], “unit“) or
ChannelSilenceVoice([“channelName“] or [channelId], “name“)
Only a raid/party/battleground leader or assistant can silence a player.
Arguments:
channelNameName of a channel (string)
channelIdIndex of a channel (number)
unitUnit to silence (string,unitID)
nameName of a character to silence (string)
ChannelToggleAnnouncements
Enables or disables printing of join/leave announcements for a channel.
ChannelToggleAnnouncements(“channel“)
Arguments:
channelName of the channel for which to enable or disable announcements
(string)
ChannelUnSilenceAll
Unsilences a character for chat and voice on a channel.
ChannelUnSilenceAll(“channelName“, [“unit“] or [“name“]) or
ChannelUnSilenceAll(channelId, [“unit“] or [“name“]) or
ChannelUnSilenceAll([“channelName“] or [channelId], “unit“) or
ChannelUnSilenceAll([“channelName“] or [channelId], “name“)
Arguments:
channelNameName of a channel (string)
channelIdIndex of a channel (number)
unitUnit to unsilence (string,unitID)
nameName of a character to unsilence (string)
ChannelUnSilenceVoice
Unsilences a character on a chat channel.
ChannelUnSilenceVoice(“channelName“, [“unit“] or [“name“]) or
ChannelUnSilenceVoice(channelId, [“unit“] or [“name“]) or
ChannelUnSilenceVoice([“channelName“] or [channelId], “unit“) or
ChannelUnSilenceVoice([“channelName“] or [channelId], “name“)
Arguments:
channelNameName of a channel (string)
channelIdIndex of a channel (number)
unitUnit to unsilence (string,unitID)
nameName of a character to unsilence (string)
ChannelUnban
Lifts the ban preventing a character from joining a chat channel.
ChannelUnban(“channel“, “fullname“)
Has no effect unless the player is a moderator of the given channel
606 Part IV Reference
Arguments:
channelName of the channel (string)
fullnameName of the character to for which to lift the ban (string)
ChannelUnmoderator
Revokes moderator status from a character on a chat channel.
ChannelUnmoderator(“channel“, “fullname“)
Has no effect unless the player is the owner of the given channel
Arguments:
channelName of the channel (string)
fullnameName of the character to demote from moderator (string)
ChannelUnmute
Removes a character’s ability to speak in a moderated chat channel.
ChannelUnmute(“channelName“, “name“) or ChannelUnmute(channelId, “name“)
Arguments:
channelNameName of a channel (string)
channelIdIndex of a channel (number)
nameName of a character to unmute (string)
ChannelVoiceOff
Disables voice chat in a channel.
ChannelVoiceOff(“channel“) or ChannelVoiceOff(channelIndex)
Arguments:
channelName of a channel (string)
channelIndexIndex of a channel (number)
ChannelVoiceOn
Enables voice chat in a channel.
ChannelVoiceOn(“channel“) or ChannelVoiceOn(channelIndex)
Arguments:
channelName of a channel (string)
channelIndexIndex of a channel (number)
Blizzard UI ChatFrame_AddMessageEventFilter
Adds a function to filter or alter messages to the chat display system.
ChatFrame_AddMessageEventFilter(“event“, filter)
The filter function will be called each time a message is sent to one of the
default chat frames (ChatFrame1, ChatFrame2, ..., ChatFrame7). The function
will be passed the chat frame object that the message is being added to, along
with the event that caused the messages to be added, and the arguments to that
event.
Chapter 27 API Reference 607
A filter function may return true if the message should be filtered, or false if
the message should be displayed. Following this boolean flag, the message can
return a list of (possibly) altered arguments to be passed to the next filter
function.
See examples for details.
Arguments:
event—A CHAT_MSG_ Event for which the filter should be used (string)
filterA function to filter incoming messages (function)
Examples:
-- Example #1
-- a filter to hide all yelled messaged containing certain text
function noGoldSpam(self,event,msg)
local badWords = {“gold“,“%$“,“www“,“%.com“,“%.net“,“%.org“}
local matchCount = 0;
for _, word in ipairs(badWords) do
if (string.match(msg, word)) then
matchCount = matchCount + 1;
end
end
if (matchCount > 1) then
return true;
else
return false;
end
end
ChatFrame_AddMessageEventFilter(“CHAT_MSG_YELL“,noGoldSpam)
-- Example #2
-- a filter to display icons next to item links in loot messages
function addLootIcons(self, event, msg, ...)
local _, fontSize = GetChatWindowInfo(self:GetID())
local function iconForLink(link)
local texture = GetItemIcon(link)
return “\124T“..texture..“:“..fontSize..“\124t“..link
end
msg = string.gsub(msg,“(\124c%x+\124Hitem:.-\124h\124r)“,iconForLink)
return false, msg, ...
end
ChatFrame_AddMessageEventFilter(“CHAT_MSG_LOOT“, addLootIcons)
Blizzard UI ChatFrame_GetMessageEventFilters
Returns the list of filters registered for a chat event.
filterTable = ChatFrame_GetMessageEventFilters(“event“)
See ChatFrame_AddMessageEventFilter() for details about chat message
filters.
Arguments:
event—A CHAT_MSG_ Event (string)
608 Part IV Reference
Returns:
filterTableA table containing any filters set for the given event,
with numeric keys corresponding to the order in which filters were registered
(table)
Blizzard UI ChatFrame_RemoveMessageEventFilter
Removes a previously set chat message filter.
ChatFrame_RemoveMessageEventFilter(“event“, filter)
See ChatFrame_AddMessageEventFilter() for details about chat message
filters.
Arguments:
eventCHAT_MSG_ Event from which to remove a filter (string)
filterA filter function registered for the event (function)
CheckBinderDist
Returns whether the player is in range of an NPC that can set the Hearthstone
location.
inRange = CheckBinderDist()
Usable following the CONFIRM_BINDER event which fires when the player
speaks to an Innkeeper (or similar) NPC and chooses to set his or her
Hearthstone location. Used in the default UI to hide the confirmation window
for such if the player moves too far away from the NPC.
Returns:
inRange1if the player is in range of an NPC that can set the Hearthstone loca-
tion; otherwise nil (1nil)
CheckInbox
Requests information on the player’s mailbox contents from the server.
Information is not returned immediately; the MAIL_INBOX_UPDATE event fires
when data becomes available for use by other Mail/Inbox API functions.
CheckInteractDistance
Returns whether the player is close enough to a unit for certain types of
interaction.
canInteract = CheckInteractDistance(“unit“, distIndex)
Arguments:
unit—A unit to query (string,unitID)
distIndexNumber identifying one of the following action types (number)
1—Inspect
2—Trade
3—Duel
4Follow
Returns:
canInteract1if the player is close enough to the other unit to perform the
action; otherwise nil (1nil)
Chapter 27 API Reference 609
CheckReadyCheckTime
Finishes a ready check initiated by the player.
Causes the READY_CHECK_FINISHED event to fire. Only has an effect
30 seconds after starting a ready check.
CheckSpiritHealerDist
Returns whether the player is in range of a spirit healer.
inRange = CheckSpiritHealerDist()
Usable following the CONFIRM_XP_LOSS event which fires upon speaking to a
spirit healer while dead and choosing the option to immediately resurrect.
Used in the default UI to hide the confirmation window for such if the player
moves too far away from the spirit healer.
Returns:
inRange1if the player is in range of a spirit healer; otherwise nil (1nil)
CheckTalentMasterDist
Returns whether the player is in range of an NPC that can reset talents.
inRange = CheckTalentMasterDist()
Usable following the CONFIRM_TALENT_WIPE event which fires when the
player speaks to a trainer NPC and chooses to reset his or her talents. Used in
the default UI to hide the confirmation window for such if the player moves
too far away from the NPC.
Returns:
inRange1if the player is in range of a talent trainer; otherwise nil (1nil)
ClearAchievementComparisonUnit
Disables comparing achievements/statistics with another player.
ClearCursor
Clears any contents attached to the cursor.
If the cursor contains an item picked up from inventory (equipment slots) or a
container, the item returns to its point of origin and the inventory or container
slot is unlocked. (To destroy an item, see DeleteCursorItem()).
If the cursor contains an action, that action is deleted (but not the spell, item,
macro, etc that it represents).
If the cursor contains any other data type, nothing happens other than the
cursor being reverted to its default state; picking up such objects has no effect
on their points of origin.
Protected ClearFocus
Clears the player’s focus unit.
ClearInspectPlayer
Ends inspection of another character.
After this function is called, data about the inspected unit may not be available
or valid.
Used in the default UI when the InspectFrame is hidden.
610 Part IV Reference
ClearLFGAutojoin
Disables the option to automatically join a group matching current LFG
criteria.
ClearLFMAutofill
Disables the option to automatically fill the player’s group when Looking for
More.
ClearLookingForGroup
Cancels active LFG searches, removing the player from the LFG queue.
ClearLookingForMore
Cancels active LFM searches, removing the player from the LFG queue.
ClearOverrideBindings
Clears any registered override bindings for a given owner.
ClearOverrideBindings(owner)
An override binding is a temporary key or click binding that can be used to
override the default bindings. The bound key will revert to its normal setting
once the override has been removed.
Arguments:
ownerA Frame (or other widget) object for which override bindings are regis-
tered (table)
Protected ClearPartyAssignment
Removes a group role assignment from a member of the player’s party or raid.
ClearPartyAssignment(“assignment“ [, “unit“]) or
ClearPartyAssignment(“assignment“ [, “name“ [, exactMatch]])
If no unit (or name) is given, removes the role assignment from all members of
the party or raid.
Arguments:
assignmentA group role to assign to the unit (string)
MAINASSISTRemove the main assist role
MAINTANKRemove the main tank role
unit (optional)A unit in the player’s party or raid (string,unitID)
name (optional)Name of a unit in the player’s party or raid (string)
exactMatch (optional)True to check only units whose name exactly
matches the name given; false to allow partial matches (boolean)
ClearSendMail
Clears any text, items, or money from the mail message to be sent.
Protected ClearTarget
Clears the player’s current target.
ClearTutorials
Disables contextual tutorial display.
Chapter 27 API Reference 611
ClickAuctionSellItemButton
Picksupanitemfromorputsanitemintothe‘CreateAuction’slot.
If the cursor is empty and the slot contains an item, that item is put onto the
cursor. If the cursor contains an item and the slot is empty, the item is placed
into the slot. If both the cursor and the slot contain items, the contents of the
cursor and the slot are exchanged.
Only has effect if the player is interacting with an auctioneer (i.e. between the
AUCTION_HOUSE_SHOW and AUCTION_HOUSE_CLOSED events). Causes an error
message (UI_ERROR_MESSAGE) if the item on the cursor cannot be put up for
auction (e.g. if the item is soulbound).
Example:
-- Places the first item in your backpack in the auction house item slot
PickupContainerItem(0, 1)
ClickAuctionSellItemButton()
ClickLandmark
Processes a hyperlink associated with a map landmark.
ClickLandmark(mapLinkID)
Possible landmarks include PvP objectives (both in battlegrounds and in world
PvP areas), town and city markers on continent maps, and special markers
such as those used during the Scourge Invasion world event. Some landmarks
(such as those for towns on a zone map) exist but are not visible in the default
UI.
Hyperlinks are not used for any of the landmarks currently in the game; this
function does nothing when called with a landmark which does not have a
hyperlink.
Arguments:
mapLinkIDHyperlink ID associated with a map landmark, as retrieved from
GetMapLandmarkInfo() (number)
ClickSendMailItemButton
Picksupanitemfromorputsanitemintoanattachmentslotforsendingmail.
ClickSendMailItemButton(index, autoReturn)
If the cursor is empty and the mail attachment slot contains an item, that item
is put onto the cursor. If the cursor contains an item and the slot is empty, the
item is placed into the slot. If both the cursor and the slot contain items, the
contents of the cursor and the mail attachment slot are exchanged.
Only has effect if the player is interacting with a mailbox (i.e. between the
MAIL_SHOW and MAIL_CLOSED events). Causes an error message
(UI_ERROR_MESSAGE) if an invalid mail attachment slot is specified or if the
item on the cursor cannot be mailed (e.g. if the item is soulbound).
Arguments:
indexIndex of a mail attachment slot (between 1and ATTACHMENTS_MAX
_SEND)(number)
612 Part IV Reference
autoReturnTrue to automatically return the item in the given attach-
ment slot to the player’s bags; false or omitted to put the item on the cursor
(boolean)
Example:
-- Places the first item in your backpack in the auction house item slot
PickupContainerItem(0, 1)
ClickSendMailItemButton()
ClickSocketButton
Picks up or places a gem in the Item Socketing UI.
ClickSocketButton(index)
If the Item Socketing UI is open and the cursor contains a socketable gem,
places the gem into socket index. If the cursor does not hold an item and
socket index is not locked, picks up the gem in that socket.
Only has an effect while the Item Socketing UI is open (i.e. between the
SOCKET_INFO_UPDATE and SOCKET_INFO_CLOSE events).
Arguments:
indexIndex of a gem socket (between 1and GetNumSockets())(number)
Example:
-- Put the item in the top left slot of the backpack into the
-- first gem socket
PickupContainerItem(0,1)
ClickSocketButton(1)
ClickStablePet
Inspects or moves a pet in the Pet Stable UI.
selected = ClickStablePet(index)
Action taken depends on cursor contents as well as the index passed:
If the cursor does not contain a pet, selects the given pet slot.
If the cursor contains the active pet and index is a stable slot, places the
pet into the stable (but not necessarily into the given slot).
If the cursor contains a stabled pet, and index is 0, makes the stabled
pet the active pet (and puts the active pet into the stable).
Arguments:
index—Index of a stable slot (number)
0—Active pet
1 to NUM_PET_STABLE_SLOTSA stable slot
Returns:
selected1if the function selected a stabled pet, rather than placed a pet in
the stable slot (1nil)
ClickTargetTradeButton
Interacts with an item in a slot offered for trade by the target.
ClickTargetTradeButton(index)
Chapter 27 API Reference 613
Only meaningful when used with the last (7th) trade slot: if an
enchantment-type spell is currently awaiting a target (i.e. the glowing hand
cursor is showing), targets the item in the given trade slot for the enchantment.
(The enchantment to be applied then shows for both parties in the trade, but is
not actually performed until both parties accept the trade.)
Arguments:
indexIndex of an item slot on the target’s side of the trade window (between
1and MAX_TRADE_ITEMS)(number)
ClickTradeButton
Picksupanitemfromorputsaniteminaslotofferedfortradebytheplayer.
ClickTradeButton(index)
Results vary by context:
If an item is on the cursor and no item is in the trade slot, the item
is put into the trade slot and the cursor becomes empty
If no item is on the cursor and an item is in the trade slot, the
item is put on the cursor and removed from the trade slot
If an item is on the cursor and an item is in the trade slot, the item from the
cursor is put into the trade slot and the item from the trade slot is put on
the cursor
If both cursor and trade slot are empty, nothing happens
Arguments:
indexIndex of an item slot on the player’s side of the trade window (between
1and MAX_TRADE_ITEMS)(number)
Example:
-- with the Trade UI already open, puts the item in the first
-- backpack slot into the first trade slot
PickupContainerItem(0,1)
ClickTradeButton(1)
CloseArenaTeamRoster
Ends interaction with the Arena Team Roster.
Called in the default UI when closing the Arena Team Roster frame. After this
function is called, roster information functions may no longer return valid data.
CloseAuctionHouse
Ends interaction with the Auction House UI.
Causes the AUCTION_HOUSE_CLOSED event to fire, indicating
that Auction-related APIs may be unavailable or no longer return valid data.
CloseBankFrame
Ends interaction with the bank.
Causes the BANKFRAME_CLOSED event to fire, indicating that APIs querying
bank contents may no longer return valid results.
614 Part IV Reference
CloseBattlefield
Ends interaction with the battleground queueing UI.
Causes the BATTLEFIELDS_CLOSED event to fire, indicating that Battlefield
queueing-related APIs may no longer have effects or return valid data.
CloseGossip
Ends an NPC ‘‘gossip’’ interaction.
Causes the GOSSIP_CLOSED event to fire, indicating that Gossip APIs may no
longer have effects or return valid data.
CloseGuildBankFrame
Ends interaction with the guild bank vault.
Fires the GUILDBANKFRAME_CLOSED event, indicating that APIs related to the
Guild Bank vault may no longer have effects or return valid data. (APIs related
to guild bank permissions are still usable.)
CloseGuildRegistrar
Ends interaction with a guild registrar.
Fires the GUILD_REGISTRAR_CLOSED event, indicating that guild registrar
APIs may no longer have effects or return valid data.
CloseItemText
Ends interaction with a text object or item.
Causes the ITEM_TEXT_CLOSED event to fire, indicating that ItemText APIs are
no longer valid.
Called by the default UI when closing the ItemTextFrame, which is used for
both readable world objects (books, plaques, gravestones, etc) and readable
items (looted books, various quest-related scrolls and parchments, saved mail
messages, etc).
CloseLoot
Ends interaction with a lootable corpse or object.
Causes the LOOT_CLOSED event to fire, indicating that Loot APIs may no
longer have effects or return valid data.
If the corpse was designated as the player’s loot (via the Round Robin, Group
Loot, or Need Before Greed loot methods), the corpse’s loot becomes available
to the rest of the group. If (and only if) the loot was generated from
Disenchanting, Prospecting, Milling or similar, all loot items are automatically
picked up.
CloseMail
Ends interaction with a mailbox.
Fires the MAIL_CLOSED event, indicating that Mail/Inbox APIs may no longer
have effects or return valid data.
CloseMerchant
Ends interaction with a vendor.
Chapter 27 API Reference 615
Causes the MERCHANT_CLOSED event to fire, indicating that Merchant APIs
may no longer have effects or return valid data.
ClosePetStables
Ends use of the Pet Stables UI/API.
Causes the PET_STABLE_CLOSED event to fire, indicating that stables-related
APIs are no longer valid.
ClosePetition
Ends interaction with a petition.
Fires the PETITION_CLOSED event, indicating that Petition APIs may no longer
have effects or return valid data.
ClosePetitionVendor
Ends interaction with an arena registrar.
Fires the PETITION_VENDOR_CLOSED event, indicating that arena registrar
APIs may no longer have effects or return valid data.
CloseQuest
Ends interaction with a questgiver.
Fires the QUEST_FINISHED event, indicating that questgiver-related APIs may
no longer have effects or return valid data.
CloseSocketInfo
Ends interaction with the Item Socketing UI, discarding any changes made.
Causes the SOCKET_INFO_CLOSE event to fire, indicating that Socket API
functions may no longer have effects or return valid data.
CloseTabardCreation
Ends interaction with the guild tabard creator.
Fires the CLOSE_TABARD_FRAME event, indicating that tabard creation APIs
may no longer have effects or return valid data.
CloseTaxiMap
Ends interaction with the Taxi (flight master) UI.
Causes the TAXIMAP_CLOSED event to fire, indicating that Taxi APIs may no
longer have effects or return valid data.
CloseTrade
Ends interaction with the Trade UI, canceling any trade in progress.
Causes the TRADE_CLOSED event to fire, indicating that Trade APIs may no
longer have effects or return valid data.
CloseTradeSkill
Ends interaction with the Trade Skill UI.
Fires the TRADE_SKILL_CLOSE event, indicating that TradeSkill APIs may no
longer have effects or return valid data.
CloseTrainer
Ends interaction with a trainer.
616 Part IV Reference
Fires the TRAINER_CLOSED event, indicating that Trainer APIs may no longer
have effects or return valid data.
CollapseAllFactionHeaders
Collapses all headers and sub-headers in the Reputation UI.
This function works for both major groups (Classic, Burning Crusade, Wrath of
the Lich King, Inactive, etc.) and the sub-groups within them (Alliance Forces,
Steamwheedle Cartel, Horde Expedition, Shattrath City, etc.).
CollapseChannelHeader
Collapses a group header in the chat channel listing.
CollapseChannelHeader(index)
Arguments:
indexIndex of a header in the display channel list (between 1and
GetNumDisplayChannels())(number)
CollapseFactionHeader
Collapses a given faction header or sub-header in the Reputation UI.
CollapseFactionHeader(index)
Faction headers include both major groups (Classic, Burning Crusade, Wrath
of the Lich King, Inactive, etc.) and the sub-groups within them (Alliance
Forces, Steamwheedle Cartel, Horde Expedition, Shattrath City, etc.).
Arguments:
indexIndex of an entry in the faction list; between 1and GetNumFactions()
(number)
CollapseQuestHeader
Collapses a header in the quest log.
CollapseQuestHeader(questIndex)
Arguments:
questIndexIndex of a header in the quest log (between 1and
GetNumQuestLogEntries()), or 0 to collapse all headers (number)
CollapseSkillHeader
Collapses a group header in the Skills UI.
CollapseSkillHeader(index)
If index specifies a group header in the list, the group is collapsed; if it
specifies a skill, the header containing the skill is collapsed.
Arguments:
indexIndex of an entry in the skills list (between 1and GetNumSkill
Lines())(number)
CollapseTradeSkillSubClass
Collapses a group header in the trade skill listing.
CollapseTradeSkillSubClass(index)
Causes an error if index does not refer to a header.
Chapter 27 API Reference 617
Arguments:
indexIndex of a header in the trade skill list (between 1and
GetNumTradeSkills())(number)
CollapseTrainerSkillLine
Collapses a group header in the trainer service listing.
CollapseTrainerSkillLine(index)
Causes a Lua error if the entry is not a header (see
GetTrainerServiceInfo()).
Arguments:
indexIndex of a header in the trainer service listing (between 1and
GetNumTrainerServices()), or 0 to collapse all headers (number)
CombatLogAddFilter
Adds a filter to the combat log system.
CombatLogAddFilter(“events“, “srcGUID“, [“destGUID“] or [destMask]) or
CombatLogAddFilter(“events“, srcMask, [“destGUID“] or [destMask]) or
CombatLogAddFilter(“events“, [“srcGUID“] or [srcMask], “destGUID“) or
CombatLogAddFilter(“events“, [“srcGUID“] or [srcMask], destMask)
Each time this function is called a new filter is added to the combat log system.
Any combat log entry that passes the filter will be fired as a
COMBAT_LOG_EVENT event in order from oldest to newest.
Arguments:
eventsName of a combat log event type to include in the filtered
list, or a comma-separated list of multiple names (string)
srcGUIDGUID of the source unit (string,guid)
srcMaskBit mask of the source unit (number, bitfield)
destGUIDGUID of the destination unit (string,guid)
destMaskBit mask of the destination unit (number, bitfield)
CombatLogAdvanceEntry
Advances the ‘‘cursor’’ position used by other CombatLog functions.
hasEntry = CombatLogAdvanceEntry(count, ignoreFilter)
Information about the entry at the ‘‘cursor’’ position can be retrieved with
CombatLogGetCurrentEntry(). That function then advances the cursor to
the next entry, so calling it repeatedly returns all information in the combat log;
this function can be used to ‘‘rewind’’ the combat log to retrieve information
about earlier events or skip entries without retrieving their information.
Arguments:
countNumber of entries by which to advance the ‘‘cursor‘‘; can be negative to
move to a previous entry (number)
ignoreFilterTrue to use the entire saved combat log history; false
or omitted to use only events matching the current filter (boolean)
Returns:
hasEntry1if an entry exists at the new cursor position; otherwise nil (1nil)
618 Part IV Reference
CombatLogClearEntries
Removes all entries from the combat log.
CombatLogGetCurrentEntry
Returns the combat log event information for the current entry and advances
to the next entry.
timestamp, event, srcGUID, srcName, srcFlags, destGUID, destName, i
destFlags, ... = CombatLogGetCurrentEntry([ignoreFilter])
See COMBAT_LOG_EVENT for details of the event information.
The combat log maintains a ‘‘cursor’’ in the list of entries; this function returns
information about the event at the cursor position and advances the cursor to
the next entry. Since this function is used by the default UI’s combat log
display, the cursor position is usually at the end of the log; calling it thus
returns nothing. The function CombatLogSetCurrentEntry() can be used to
‘‘rewind’’ the combat log cursor, enabling retrieval of information about earlier
events.
Arguments:
ignoreFilter (optional)True to use the entire saved combat log history;
false or omitted to use only events matching the current filter (boolean)
Returns:
timestampTime at which the event occurred (same format as
time() and date(), but with millisecond precision) (number)
eventType of combat log event (string)
srcGUIDGUID of the unit that initiated the event (string,guid)
srcNameName of the unit that initiated the event (string)
srcFlagsFlags indicating the nature of the source unit (number, bitfield)
destGUIDGUID of the unit that was the target of the event (string,guid)
destNameName of the unit that was the target of the event (string)
destFlagsFlags indicating the nature of the target unit (number, bitfield)
...Additional arguments specific to the event type (list)
CombatLogGetNumEntries
Returns the number of available combat log events.
CombatLogGetNumEntries(ignoreFilter)
Arguments:
ignoreFilterTrue to use the entire saved combat log history; false
or omitted to use only events matching the current filter (boolean)
CombatLogGetRetentionTime
Returns the amount of time combat log entries are stored.
seconds = CombatLogGetRetentionTime()
Returns:
secondsAmount of time entries remain available (number)
Chapter 27 API Reference 619
CombatLogResetFilter
Removes any filters applied to the combat log.
CombatLogSetCurrentEntry
Sets the ‘‘cursor’’ position used by other CombatLog functions.
CombatLogSetCurrentEntry(index [, ignoreFilter])
Information about the entry at the ‘‘cursor’’ position can be retrieved with
CombatLogGetCurrentEntry(). That function then advances the cursor to
the next entry, so calling it repeatedly returns all information in the combat log;
this function can be used to ‘‘rewind’’ the combat log to retrieve information
about earlier events.
The argument index can be positive or negative: positive indices start at the
beginning of the combat log (oldest events) and count up to the end (newest
events); negative indices start at -1 for the newest event and count backwards
to -CombatLogGetNumEntries(ignoreFilter) for the oldest.
Arguments:
indexIndex of a combat log event (between 1and CombatLogGetNum
Entries(ignoreFilter), or between -1 and -CombatLogGetNumEntries
(ignoreFilter))(number)
ignoreFilter (optional)True to use the entire saved combat log history;
false or omitted to use only events matching the current filter (boolean)
CombatLogSetRetentionTime
Sets the amount of time combat log entries will be stored.
CombatLogSetRetentionTime(seconds)
Arguments:
seconds—The desired time (number)
CombatLog_Object_IsA
Returns whether an entity from the combat log matches a given filter.
isMatch = CombatLog_Object_IsA(unitFlags, mask)
Arguments:
unitFlagsSource or destination unit flags from a combat log entry (number,
bitfield)
maskOne of the following global constants: (number, bitfield)
COMBATLOG_FILTER_EVERYTHINGAny entity
COMBATLOG_FILTER_FRIENDLY_UNITSEntity is a friendly unit
COMBATLOG_FILTER_HOSTILE_PLAYERSEntity is a hostile player unit
COMBATLOG_FILTER_HOSTILE_UNITSEntity is a hostile non-player unit
COMBATLOG_FILTER_MEEntity is the player
COMBATLOG_FILTER_MINEEntity is a non-unit object belonging to the
player;e.g.atotem
COMBATLOG_FILTER_MY_PETEntity is the player’s pet
COMBATLOG_FILTER_NEUTRAL_UNITSEntity is a neutral unit
620 Part IV Reference
COMBATLOG_FILTER_UNKNOWN_UNITSEntity is a unit currently unknown
to the WoW client
Returns:
isMatch1if the entity flags match the given mask (1nil)
CombatTextSetActiveUnit
Sets the main unit for display of floating combat text.
CombatTextSetActiveUnit(unit)
Certain types of floating combat text are only displayed for the ‘‘active’’ unit
(normally the player): incoming damage, incoming heals, mana/energy
/power gains, low health/mana warnings, etc. This function is used by the
default UI to allow the player’s vehicle to ‘‘stand in’’ for the player for
purposes of combat text; using this function with units other than ‘‘player’’ or
‘‘vehicle’’ has no effect.
Arguments:
unitUnit to show main combat text for (unitid)
ComplainChat
Reports a chat message as spam.
ComplainChat(lineID) or ComplainChat(“name“ [, “text“])
Used in the default UI when right-clicking the name of a player in a chat
message and choosing ‘‘Report Spam’’ from the menu.
Arguments:
lineIDUnique identifier of a chat message (11th argument received with the
corresponding CHAT_MSG event) (number)
nameName of a player to complain about (string)
text (optional)Specific text to complain about (string)
ComplainInboxItem
Reports a mail message as spam.
ComplainInboxItem(mailID)
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
CompleteQuest
Begins turning in a quest to a questgiver.
Usable following the QUEST_PROGRESS event in which it is determined
whether the player can complete the quest.
Does not complete the quest turn-in process; after calling this function, the
QUEST_COMPLETE event fires as the questgiver presents rewards (or sometimes
only closure to the quest narrative); following that event, the GetQuest
Reward() function finishes the turn-in.
Chapter 27 API Reference 621
ConfirmAcceptQuest
Accepts a quest started by another group member.
Usable following the QUEST_ACCEPT_CONFIRM event which fires when another
member of the player’s party or raid starts certain quests (e.g. escort quests).
Confirmation ConfirmBindOnUse
Confirms using an item, if using the item causes it to become soulbound.
Usable in response to the USE_BIND_CONFIRM which fires when the player
attempts to use a ‘‘Bind on Use’’ item.
ConfirmBinder
Sets the player’s Hearthstone to the current location.
Usable in response to the CONFIRM_BINDER event which fires upon speaking to
an Innkeeper (or similar NPC) and choosing the Hearthstone option.
Confirmation ConfirmLootRoll
Confirms the player’s intent regarding an item up for loot rolling.
ConfirmLootRoll(id, rollType)
Usable after the CONFIRM_LOOT_ROLL event fires, warning that an item binds
on pickup.
Arguments:
idIndex of an item currently up for loot rolling (as provided in the
START_LOOT_ROLL event) (number)
rollTypeType of roll action to perform (number)
0Pass (declines the loot)
1Roll ‘‘need’’ (wins if highest roll)
2Roll ‘‘greed’’ (wins if highest roll and no other member rolls ‘‘need‘‘)
Confirmation ConfirmLootSlot
Confirms picking up an item available as loot.
ConfirmLootSlot(slot)
Usable after the LOOT_BIND_CONFIRM event fires, warning that an item binds
on pickup.
Arguments:
slotIndex of a loot slot (between 1and GetNumLootItems())(number)
ConfirmReadyCheck
Responds to a ready check.
ConfirmReadyCheck(ready)
Arguments:
readyTrue to report as ‘‘ready‘‘; false to report as ‘‘not ready’’ (true)
ConfirmSummon
Accepts an offered summons, teleporting the player to the summoner’s
location.
622 Part IV Reference
Usable between when the CONFIRM_SUMMON event fires (due to a summoning
spell cast by another player) and when the value returned by GetSummon
ConfirmTimeLeft() reaches zero.
Confirmation ConfirmTalentWipe
Resets the player’s talents.
Usable following the CONFIRM_TALENT_WIPE event which fires when the
player speaks to a trainer NPC and chooses to reset his or her talents.
ConsoleAddMessage
Prints text to the debug console.
The debugging console can be activated by launching WoW from the
command line with the ‘‘-console’’ option, then pressing the ‘‘`’’
(backtick/tilde) key ingame. Its usefulness outside of Blizzard internal
environments is limited.
ConsoleExec
Runs a console command.
ConsoleExec(“console_command“)
Used by the default UI to handle /console commands.
Arguments:
console_commandThe console command to run (string)
ContainerIDToInventoryID
Returns the inventoryID corresponding to a given containerID.
inventoryID = ContainerIDToInventoryID(container)
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
Returns:
inventoryIDIdentifier for the container usable with Inventory APIs (number,
inventoryID)
Example:
-- Switches the player’s first bag (the one immediately left of the
-- backpack) with the first bank bag (or puts the bag into the bank
-- if the bank bag slot is empty)
local firstBagSlot = ContainerIDToInventoryID(1)
local firstBankBagSlot = ContainerIDToInventoryID(5)
PickupInventoryItem(firstBagSlot)
PickupInventoryItem(firstBankBagSlot)
ContainerRefundItemPurchase
Sells an item purchased with alternate currency back to a vendor.
ContainerRefundItemPurchase(container, slot)
Items bought with alternate currency (honor points, arena points, or special
items such as Emblems of Heroism and Dalaran Cooking Awards) can be
Chapter 27 API Reference 623
returned to a vendor for a full refund, but only within a limited time after the
original purchase.
Arguments:
containerIndex of one of the player’s bags or other containers (number,con-
tainerID)
slotIndex of an item slot within the container (number, containerSlotID)
ConvertToRaid
Converts a party to a raid.
Only has effect if the player is in a party and the party leader.
CreateFont
Creates a new Font object.
fontObject = CreateFont(“name“)
Arguments:
nameName to assign to the newly created object; used both as the name of
the object (retrievable with Font:GetName()) and as a global variable referenc-
ing the object (unless another global by that name already exists) (string)
Returns:
fontObjectThe newly created Font object (table)
CreateFrame
Creates a new Frame object.
frame = CreateFrame(“frameType“ [, “name“ [, parent [, “template“]]])
Arguments:
frameTypeType of frame to create; see the widget documentation for details
(string)
name (optional)Name to assign to the newly created object; used both as
the name of the object (retrievable via the GetName method) and as a global
variable referencing the object, unless another global by that name already exists
(string)
parent (optional)Reference to another frame to be the new frame’s parent
(table)
template (optional)Name of a template to be used in creating the frame;
if creating a frame from multiple templates, a comma-separated list of names
(string)
Returns:
frameA reference to the newly created Frame (table)
Example:
-- creates a generic button in the middle of the screen
mybutton = CreateFrame(“Button“,“mybutton“,UIParent, i
“UIPanelButtonTemplate“)
mybutton:SetPoint(“CENTER“,0,0)
mybutton:SetWidth(80)
mybutton:SetHeight(22)
624 Part IV Reference
CreateMacro
Creates a new macro.
index = CreateMacro(“name“, icon, “body“, perCharacter)
Arguments:
nameName for the new macro (up to 16 characters); need not be unique,
though duplicate names can cause issues for other Macro API functions (string)
iconIndex of a macro icon (between 1and GetNumMacroIcons())(number)
bodyBody of the macro (up to 255 characters) (string)
perCharacter1if the macro should be stored as a character-specific macro;
otherwise nil (1nil)
Returns:
indexIndex of the newly created macro (number,macroID)
Example:
-- Create a character specific macro
local index = CreateMacro(“DanceMonkey“, 13, “/emote dances like a i
monkey!!!“, 1)
-- Create a general macro
local index = CreateMacro(“Heal“, 73, “/cast Flash Heal\n/say Let i
the light of Elune cleanse you!“)
CursorCanGoInSlot
Returns whether the item on the cursor can be equipped in an inventory slot.
canBePlaced = CursorCanGoInSlot(slot)
Returns nil if the cursor is empty or contains something other than an item.
Arguments:
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
Returns:
canBePlaced1if the item on the cursor can be equipped in the given slot; oth-
erwise nil (1nil)
CursorHasItem
Returns whether an item is on the cursor.
hasItem = CursorHasItem()
See GetCursorInfo() for more detailed information.
Returns:
hasItem1if the cursor is currently holding an item; otherwise nil (1nil)
CursorHasMacro
Returns whether a macro is on the cursor.
hasMacro = CursorHasMacro()
See GetCursorInfo() for more detailed information.
Chapter 27 API Reference 625
Returns:
hasMacro1if the cursor is currently holding a macro; otherwise nil (1nil)
CursorHasMoney
Returns whether an amount of the player’s money is on the cursor.
hasMoney = CursorHasMoney()
Returns nil if the cursor holds guild bank money. See GetCursorInfo() for
more detailed information.
Returns:
hasMoney1if the cursor is currently holding an amount of the player’s money;
otherwise nil (1nil)
CursorHasSpell
Returns whether a spell is on the cursor.
hasSpell = CursorHasSpell()
See GetCursorInfo() for more detailed information.
Returns:
hasSpell1if the cursor is currently holding a spell; otherwise nil (1nil)
DeclineArenaTeam
Declines an arena team invitation.
DeclineGroup
Declines an invitation to join a party or raid.
Usable in response to the PARTY_INVITE_REQUEST event which fires when the
player is invited to join a group.
DeclineGuild
Declines an offered guild invitation.
Usable in response to the GUILD_INVITE_REQUEST event which fires when the
player is invited to join a guild.
DeclineInvite
Declines an invitation to a chat channel.
DeclineInvite(“channel“)
Usable in response to the CHANNEL_INVITE_REQUEST event which fires when
the player is invited to join a chat channel.
Arguments:
channelName of a chat channel (string)
DeclineLFGMatch
Declines a proposed LFG match.
Usable after a group match has been proposed to the player via the
LFG_MATCH_REQUEST event.
DeclineLevelGrant
Refuses a level offered by the player’s Recruit-a-Friend partner.
626 Part IV Reference
DeclineName
Returns suggested declensions for a name.
genitive, dative, accusative, instrumental, prepositional = i
DeclineName(“name“, gender, declensionSet)
In the Russian language, nouns (including proper names) take different form
based on their usage in a sentence. When the player enters the base name for a
character or pet, the game suggests one or more sets of variations for the five
additional cases; the player is asked to choose from among the suggestions
and/or enter their own. (The set of declensions ultimately chosen/entered by
the player are only used internally and not available to addons.)
Has no effect in non-Russian-localized clients.
Arguments:
nameNominative form of the player’s or pet’s name (string)
genderGender for the returned names (for declensions of the player’s name,
should match the player’s gender; for the pet’s name, should be neuter) (number)
1ornil—Neuter
2—Male
3—Female
declensionSetIndex of a set of suggested declensions (between
1and GetNumDeclensionSets(name,gender). Lower indices
correspond to ‘‘better’’ suggestions for the given name. (number)
Returns:
genitiveGenitive form of the name (string)
dativeDative form of the name (string)
accusativeAccusative form of the name (string)
instrumentalInstrumental form of the name (string)
prepositionalPrepositional form of the name (string)
DeclineQuest
Declines a quest.
Usable following the QUEST_DETAIL event in which the questgiver presents
the player with the details of a quest and the option to accept or decline.
DeclineResurrect
Declines an offered resurrection spell.
Usable following the RESURRECT_REQUEST event which fires when the player
is offered resurrection by another unit.
DelIgnore
Removes a player from the ignore list.
DelIgnore(“name“)
Arguments:
nameName of a character to remove from the ignore list (string)
Chapter 27 API Reference 627
DelMute
Removes a character from the muted list for voice chat.
DelMute(“name“)
The Muted list acts for voice chat as the Ignore list does for text chat: muted
characters will never be heard regardless of which voice channels they join the
player in.
Arguments:
nameName of a character to remove from the mute list (string)
Confirmation DeleteCursorItem
Destroys the item on the cursor.
Used in the default UI when accepting the confirmation prompt that appears
when dragging and dropping an item to an empty area of the screen.
Confirmation DeleteEquipmentSet
Deletes an equipment set.
DeleteEquipmentSet(“name“)
Arguments:
nameName of an equipment set (case sensitive) (string)
Confirmation DeleteGMTicket
Abandons the currently pending GM ticket.
Confirmation DeleteInboxItem
Deletes a message from the player’s inbox.
DeleteInboxItem(mailID)
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
DeleteMacro
Deletes a macro.
DeleteMacro(index) or DeleteMacro(“name“)
Arguments:
index—Index of a macro (number,macroID)
name—Name of a macro (string)
DemoteAssistant
Demotes the given player from raid assistant status.
DemoteAssistant(“unit“) or DemoteAssistant(“name“ [, exactMatch])
Arguments:
unitA unit in the raid (string,unitID)
nameName of a unit in the raid (string)
exactMatch (optional)True to check only units whose name exactly
matches the name given; false to allow partial matches (boolean)
628 Part IV Reference
Confirmation DepositGuildBankMoney
Deposits money into the guild bank.
DepositGuildBankMoney(money)
Arguments:
moneyAmount of money to deposit (in copper) (number)
Protected DescendStop
Stops movement initiated by SitStandOrDescendStart.
Used by the SITORSTAND binding, which also controls descent when
swimming or flying. Has no meaningful effect if called while sitting/standing.
DestroyTotem
Destroys a specific totem (or ghoul).
DestroyTotem(slot)
Totem functions are also used for ghouls summoned by a Death Knight’s Raise
Dead ability (if the ghoul is not made a controllable pet by the Master of
Ghouls talent).
Arguments:
slotWhich totem to destroy (number)
1Fire (or Death Knight’s ghoul)
2—Earth
3—Water
4—Air
DetectWowMouse
Detects the presence of a WoW-compatible multi-button mouse.
This function is used by the default user interface to enable or disable the
configuration option for a many-buttoned WoW mouse. If the mouse is not
found, the WOW_MOUSE_NOT_FOUND event will fire.
DisableAddOn
Marks an addon as disabled.
DisableAddOn(“name“) or DisableAddOn(index)
The addon will remain active until the player logs out and back in or reloads
the UI (see ReloadUI()). Changes to the enabled/disabled state of addons
while in-game are saved on a per-character basis.
Arguments:
nameName of an addon (name of the addon’s folder and TOC file, not the Title
found in the TOC) (string)
indexIndex of an addon in the addon list (between 1and GetNumAddOns())
(number)
DisableAllAddOns
Marks all addons as disabled.
Addons will remain active until the player logs out and back in or reloads the
UI (see ReloadUI()).
Chapter 27 API Reference 629
Changes to the enabled/disabled state of addons while in-game are saved on a
per-character basis.
DisableSpellAutocast
Disables automatic casting of a pet spell.
DisableSpellAutocast(“spell“)
Arguments:
spellThe name of a pet spell (string)
DismissCompanion
Unsummons the current non-combat pet or mount.
DismissCompanion(“type“)
Arguments:
type—The type of companion (string)
CRITTERNon-combat pet
MOUNT—Mount
Dismount
Dismounts from the player’s summoned mount.
DisplayChannelOwner
Requests information from the server about a channel’s owner.
DisplayChannelOwner(“channel“) or DisplayChannelOwner(channelIndex)
Fires the CHANNEL_OWNER event indicating the name of the channel owner.
Arguments:
channelName of a channel (string)
channelIndexIndex of a channel (number)
DisplayChannelVoiceOff
Disables voice in a channel specified by its position in the channel list display.
DisplayChannelVoiceOff(index)
Arguments:
indexIndex of a channel in the channel list display (between 1and
GetNumDisplayChannels())(number)
DisplayChannelVoiceOn
Enables voice in a channel specified by its position in the channel list display.
DisplayChannelVoiceOn(index)
Arguments:
indexIndex of a channel in the channel list display (between 1and
GetNumDisplayChannels())(number)
DoEmote
Performs a preset emote (with optional target).
DoEmote(“emote“ [, “target“])
630 Part IV Reference
The list of built-in emote tokens can be found in global variables whose names
follow the format “EMOTE“..num..“_TOKEN“,wherenum is a number
between 1and MAXEMOTEINDEX (a variable local to ChatFrame.lua.)
For custom emotes (as performed using the /emote or /me commands in the
default UI), see SendChatMessage().
Arguments:
emoteNon-localized token identifying an emote to perform (string)
target (optional)Name of a unit at whom to direct the emote (string)
Example:
DoEmote(“wave“)
-- Player waves
DoEmote(“threaten“, “King Varian Wrynn“)
-- Player threatens King Varian Wrynn with the wrath of doom
DoReadyCheck
Initiates a ready check.
Only has effect if the player is the party/raid leader or a raid assistant.
DoTradeSkill
Performs a trade skill recipe.
DoTradeSkill(index [, repeat])
Arguments:
indexIndex of a recipe in the trade skill list (between 1and GetNumTrade
Skills())(number)
repeat (optional)Number of times to repeat the recipe (number)
DownloadSettings
Restores game settings from a backup stored on the server.
This function only works if server-synchronized settings are enabled. This is
controlled by the synchronizeSettings CVar.
DropCursorMoney
Drops any money currently on the cursor, returning it to where it was taken
from.
DropItemOnUnit
‘‘Gives’’ the item on the cursor to another unit; results vary by context.
DropItemOnUnit(“unit“) or DropItemOnUnit(“name“)
If the unit is a friendly player, adds the item to the trade window (opening it if
necessary, and placing it in the first available trade slot or the ‘‘will not be
traded’’ slot depending on whether the item is soulbound). If the unit is the
player’s pet and the player is a Hunter, attempts to feed the item to the pet
(since this casts the Feed Pet spell, in this case this action is protected and can
only be called by the Blizzard user interface). For other units, nothing happens
and the item remains on the cursor.
Chapter 27 API Reference 631
Arguments:
unitA unit to receive the item (string,unitID)
nameName of a unit to receive the item; only valid for player,pet,and
party/raid members (string)
No Combat EditMacro
Changes the name, icon, and/or body of a macro.
newIndex = EditMacro(index, “name“, icon, “body“)
Arguments:
indexExisting index of the macro (number,macroID)
nameNew name for the macro (up to 16 characters); nil to keep an existing
name (string)
iconIndex of a macro icon (between 1and GetNumMacroIcons()); nil to
keep an existing icon (number)
bodyBody of the macro (up to 255 characters); nil to keep the existing body
(string)
Returns:
newIndexIndex at which the macro is now saved (may differ from input
index if the macro’s name was changed, as macros are saved in alphabetical
order) (number,macroID)
EjectPassengerFromSeat
Ejects the occupant of a seat in the player’s vehicle.
EjectPassengerFromSeat(seat)
Arguments:
seatIndex of a seat in the player’s vehicle (number)
EnableAddOn
Marksanaddonasenabled.
EnableAddOn(index) or EnableAddOn(“name“)
The addon will remain inactive until the player logs out and back in or reloads
the UI (see ReloadUI()).
Changes to the enabled/disabled state of addons while in-game are saved on a
per-character basis.
Arguments:
indexThe index of the addon to be enabled (number)
nameThe name of the addon to be enabled (string)
EnableAllAddOns
Marks all addons as enabled.
Addons will remain inactive until the player logs out and back in or reloads
the UI (see ReloadUI()).
Changes to the enabled/disabled state of addons while in-game are saved on a
per-character basis.
632 Part IV Reference
EnableSpellAutocast
Enables automatic casting of a pet spell.
EnableSpellAutocast(“spell“)
Arguments:
spellName of a pet spell (string)
Confirmation EndBoundTradeable
Confirms taking an action which renders a looted Bind on Pickup item
non-tradeable.
EndBoundTradeable(id)
A Bind on Pickup item looted by the player can be traded to other characters
who were originally eligible to loot it, but only within a limited time after
looting. This period can be ended prematurely if the player attempts certain
actions (such as enchanting the item).
Arguments:
idNumber identifying the item (as provided by the END_BOUND_TRADEABLE
event) (number)
Confirmation EndRefund
Confirms taking an action which renders a purchased item non-refundable.
EndRefund(id)
Items bought with alternate currency (honor points, arena points, or special
items such as Emblems of Heroism and Dalaran Cooking Awards) can be
returned to a vendor for a full refund, but only within a limited time after the
original purchase. This period can be ended prematurely if the player attempts
certain actions (such as enchanting the item).
Arguments:
idNumber identifying the item (as provided by the END_REFUND event)
(number)
EnumerateFrames
Returns the next frame following the frame passed, or nil if no more frames
exist.
nextFrame = EnumerateFrames([currentFrame])
Arguments:
currentFrame (optional)The current frame to get the next frame, or nil to
get the first frame (table)
Returns:
nextFrameThe frame following currentFrame or nil if no more frames exist,
or the first frame if nil was passed (table)
Example:
-- Print all visible frames under the mouse cursor
local frame = EnumerateFrames(); -- Get the first frame
while frame do
Chapter 27 API Reference 633
if ( frame:IsVisible() and MouseIsOver(frame) ) then
print(frame:GetName() or string.format(“[Unnamed Frame: %s]“, i
tostring(frame)));
end
frame = EnumerateFrames(frame); -- Get the next frame
end
EnumerateServerChannels
Returns the available server channel names.
... = EnumerateServerChannels()
Returns:
...A list of strings, each the name of an available server channel (e.g. ‘‘Gen-
eral‘‘, ‘‘Trade‘‘, ‘‘WorldDefense‘‘, ‘‘GuildRecruitment‘‘, ‘‘LookingForGroup‘‘)
(string)
EquipCursorItem
Puts the item on the cursor into a specific equipment slot.
EquipCursorItem(slot)
If the item on the cursor can be equipped but does not fit in the given slot, the
item is automatically equipped in the first available slot in which it fits (as with
AutoEquipCursorItem()). Thus, this function is most useful when dealing
with items which can be equipped in more than one slot: containers, rings,
trinkets, and (for dual-wielding characters) one-handed weapons.
Causes an error message (UI_ERROR_MESSAGE) if the item on the cursor cannot
be equipped. Does nothing if the cursor does not contain an item.
Arguments:
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
EquipItemByName
Attempts to equip an arbitrary item.
EquipItemByName(itemID) or EquipItemByName(“itemName“) or i
EquipItemByName(“itemLink“)
The item is automatically equipped in the first available slot in which it fits. To
equipaniteminaspecicslot,seeEquipCursorItem().
Causes an error message (UI_ERROR_MESSAGE) if the specified item cannot be
equipped. Does nothing if the specified item does not exist or is not in the
player’s possession.
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Confirmation EquipPendingItem
Confirms equipping a bind-on-equip item.
EquipPendingItem(index)
634 Part IV Reference
Usable following the EQUIP_BIND_CONFIRM or AUTOEQUIP_BIND
_CONFIRM, which fires when the player attempts to equip a bind-on-equip item
Arguments:
indexIndex provided by the EQUIP_BIND_CONFIRM or AUTOEQUIP_BIND
_CONFIRM event; currently always 0 (number)
EquipmentManagerClearIgnoredSlotsForSave
Clears the list of equipment slots to be ignored when saving sets.
EquipmentManagerIgnoreSlotForSave
Adds an equipment slot to the list of those ignored when saving sets.
EquipmentManagerIgnoreSlotForSave(slot)
Creating or saving a set with SaveEquipmentSet() will ignore any slots on
the list, allowing the player to create sets which only switch certain items
(e.g. to equip a fishing pole and hat while leaving non-fishing-related items
equipped).
Arguments:
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
EquipmentManagerIsSlotIgnoredForSave
Returns whether the contents of an equipment slot will be included when
saving sets.
isIgnored = EquipmentManagerIsSlotIgnoredForSave(slot)
Arguments:
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
Returns:
isIgnoredTrue if the contents of the slot will not be included when
next creating or saving an equipment set; otherwise false (boolean)
EquipmentManagerUnignoreSlotForSave
Removes an equipment slot from the list of those ignored when saving sets.
EquipmentManagerUnignoreSlotForSave(slot)
Creating or saving a set with SaveEquipmentSet() will ignore any slots on
the list, allowing the player to create sets which only switch certain items
(e.g. to equip a fishing pole and hat while leaving non-fishing-related items
equipped).
Arguments:
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
EquipmentManager_UnpackLocation
Unpacks an inventory location bitfield into usable components.
player, bank, bags, location or slot, bag = i
EquipmentManager_UnpackLocation(location)
Chapter 27 API Reference 635
Arguments:
locationA bit field that represents an item’s location in the player’s pos-
session. This bit field can be obtained using the GetInventoryItemsForSlot
function. (number)
Returns:
playerA flag indicating whether or not the item exists in the player’s inven-
tory (i.e. an equipped item). (boolean)
bankA flag indicating whether or not the item exists in the payer’s bank.
(boolean)
bagsA flag indicating whether or not the item exists in the player’s bags.
(boolean)
location or slotThe inventory slot that contains the item, or the container
slot that contains the item, if the item is in the player’s bags. (number)
bagThe bagID of the container that contains the item. (number)
EquipmentSetContainsLockedItems
Returns whether an equipment set contains locked items.
isLocked = EquipmentSetContainsLockedItems(“name“)
Locked items are those in a transient statee.g. on the cursor for moving
within the player’s bags, placed in the Send Mail or Trade UIs, etc.for which
the default UI displays the item’s icon as grayed out. A set cannot be equipped
if it contains locked items.
Arguments:
nameName of an equipment set (case sensitive) (string)
Returns:
isLockedTrue if the equipment set contains locked items (boolean)
ExpandAllFactionHeaders
Expands all headers and sub-headers in the Reputation UI.
Expands headers for both major groups (Classic, Burning Crusade, Wrath of
the Lich King, Inactive, etc.) and the sub-groups within them (Alliance Forces,
Steamwheedle Cartel, Horde Expedition, Shattrath City, etc.).
ExpandChannelHeader
Expands a group header in the chat channel listing.
ExpandChannelHeader(index)
Arguments:
indexIndex of a header in the display channel list (between 1and
GetNumDisplayChannels())(number)
ExpandCurrencyList
Expands or collapses a list header in the Currency UI.
ExpandCurrencyList(index, shouldExpand)
636 Part IV Reference
Arguments:
indexIndex of a header in the currency list (between 1and GetCurrency
ListSize()) (number)
shouldExpand1to expand the header, showing its contents; 0 to collapse the
header, hiding its contents (number)
ExpandFactionHeader
Expands a given faction header or sub-header in the Reputation UI.
ExpandFactionHeader(index)
Faction headers include both major groups (Classic, Burning Crusade, Wrath
of the Lich King, Inactive, etc.) and the sub-groups within them (Alliance
Forces, Steamwheedle Cartel, Horde Expedition, Shattrath City, etc.).
Arguments:
indexIndex of an entry in the faction list; between 1and GetNumFactions()
(number)
ExpandQuestHeader
Expands a quest header in the quest log.
ExpandQuestHeader(questIndex)
Arguments:
questIndexIndex of a header in the quest log (between 1and GetNum
QuestLogEntries()), or 0 to expand all headers (number)
ExpandSkillHeader
Expands a group header in the Skills UI.
ExpandSkillHeader(index)
Arguments:
indexIndex of an entry in the skills list (between 1and GetNumSkill
Lines())(number)
ExpandTradeSkillSubClass
Expands a group header in the trade skill listing.
ExpandTradeSkillSubClass(index)
Causes an error if index does not refer to a header.
Arguments:
indexIndex of a header in the trade skill list (between 1and
GetNumTradeSkills())(number)
ExpandTrainerSkillLine
Expands a group header in the trainer service listing.
ExpandTrainerSkillLine(index)
Causes a Lua error if the entry is not a header (see
GetTrainerServiceInfo()).
Chapter 27 API Reference 637
Arguments:
indexIndex of a header in the trainer service listing (between 1and
GetNumTrainerServices()), or 0 to expand all headers (number)
FactionToggleAtWar
Toggles ‘‘at war’’ status for a faction.
FactionToggleAtWar(index)
‘‘At War’’ status determines whether members of a faction can be attacked.
Normal interactions (as with merchants, questgivers, etc.) are not available if
the player is ‘‘at war’’ with an NPC’s faction.
This function does nothing for faction headers or factions for which changing
‘‘at war’’ status is not currently allowed; i.e., factions for which the eighth
(canToggleAtWar)returnofGetFactionInfo is false or nil.
Arguments:
indexIndex of an entry in the faction list; between 1and GetNumFactions()
(number)
FillLocalizedClassList
Fills a table with localized class names keyed by non-localized class tokens.
FillLocalizedClassList(table [, female])
Note that while localized class names have no gender in English, other locales
have different names for each gender.
Arguments:
tableAn empty table to be filled (number)
female (optional)True to fill the table with female class names;
false or omitted to fill it with male class names (boolean)
Example:
-- prints the localized names for each class in the main chat window,
-- with each name in the appropriate color
local classes = {}
FillLocalizedClassList(classes, true)
for token, localizedName in pairs(classes) do
local color = RAID_CLASS_COLORS[token];
ChatFrame1:AddMessage(localizedName, color.r, color.g, color.b)
end
FlagTutorial
Marks a contextual tutorial as displayed so it doesn’t appear again.
FlagTutorial(“tutorial“)
Arguments:
tutorialNumeric identifier for the tutorial step (as string); supplied in the
TUTORIAL_TRIGGER event (string)
FlipCameraYaw
Rotates the camera around the player.
FlipCameraYaw(degrees)
638 Part IV Reference
Arguments:
degreesThe number of degrees to rotate; positive for counter-clockwise, neg-
ative for clockwise. (number)
Example:
-- Dramatically Rotate the camera 360 degrees around the player
if not YawFrame then CreateFrame(“Frame“, “YawFrame“) end
local degree = 0
local function OnUpdate(self, elapsed)
degree = degree + 1
FlipCameraYaw(1)
if degree >= 360 then
self:Hide()
end
end
YawFrame:SetScript(“OnUpdate“, OnUpdate)
YawFrame:Show()
Protected FocusUnit
Changes the focus unitID to refer to a new unit.
FocusUnit(“unit“) or FocusUnit(“name“)
Arguments:
unit—A unit to focus (string,unitID)
nameThe name of a unit to focus; only valid for player,pet, and party/raid
members (string)
FollowUnit
Causes the player character to automatically follow another unit.
FollowUnit(“unit“) or FollowUnit(“name“ [, strict])
Only friendly player units can be followed.
Arguments:
unitA unit to follow (string,unitID)
nameName of a unit to follow (string)
strict (optional)True if only an exact match for the given name
should be allowed; false to allow partial matches (boolean)
ForceQuit
Immediately exits World of Warcraft.
Unlike Quit(), this function exits the game application regardless of current
conditions.
Used in the default UI when the player chooses ‘‘Exit now’’ in the dialog that
appears if the player attempts to quit while not in an inn, major city, or other
‘‘rest’’ area.
FrameXML_Debug
Enables or disables logging of XML loading.
FrameXML_Debug(enable)
Chapter 27 API Reference 639
When logging is enabled, status and error text will be saved to the file Logs/
FrameXML.log (path is relative to the folder containing the World of Warcraft
client) as the client parses and loads XML files in the default UI and addons.
Arguments:
enableTrue to enable verbose XML logging; false to disable (boolean)
GMResponseNeedMoreHelp
Requests further GM interaction on a ticket to which a GM has already
responded.
GMResponseResolve
Notifies the server that the player’s GM ticket issue has been resolved.
GMSurveyAnswer
Returns text of multiple-choice question answers in a GM survey.
answerText = GMSurveyAnswer(questionIndex, answerIndex)
Arguments:
questionIndexIndex of a survey question (between 1and MAX_SURVEY
_QUESTIONS)(number)
answerIndexIndex of one of the question’s answers (between 1and
MAX_SURVEY_ANSWERS)(number)
Returns:
answerTextText of the answer choice (string)
GMSurveyAnswerSubmit
Submits an answer to a GM survey question.
GMSurveyAnswerSubmit(question, rank, “comment“)
Arguments:
questionThe index of the question being answered (number)
rankThe rank selected (number)
commentA comment for the given question (string)
GMSurveyCommentSubmit
Submits a comment to the current GM survey.
GMSurveyCommentSubmit(“comment“)
Arguments:
commentThe comment made on the GM Survey (string)
GMSurveyQuestion
Returns the text of a specific question from a GM survey.
surveyQuestion = GMSurveyQuestion(index)
Arguments:
indexThe index of a GM survey question (number)
Returns:
surveyQuestionThe question being asked (string)
640 Part IV Reference
GMSurveySubmit
Submits the current GM survey.
GameMovieFinished
Ends in-game movie playback.
GetAbandonQuestItems
Returns information about items that would be destroyed by abandoning a
quest.
items = GetAbandonQuestItems()
Usable after calling SetAbandonQuest() but before calling AbandonQuest().
Returns:
itemsA string listing any items that would be destroyed (string)
GetAbandonQuestName
Returns the name of the quest being abandoned.
name = GetAbandonQuestName()
Usable after calling SetAbandonQuest() but before calling AbandonQuest().
Returns:
nameName of the quest being abandoned (string)
GetAccountExpansionLevel
Returns the most recent of WoW’s retail expansion packs for which the
player’s account is authorized.
expansionLevel = GetAccountExpansionLevel()
Used in the default UI to determine the player’s maximum possible level (and
showing or hiding the XP bar accordingly). Also indicates whether the player
is allowed to access expansion areas (e.g. Outland, Draenei / Blood Elf starting
areas, Northrend).
Returns:
expansionLevelExpansion level of the player’s account (number)
0World of Warcraft (‘‘Classic‘‘)
1World of Warcraft: The Burning Crusade
2World of Warcraft: Wrath of the Lich King
Example:
-- Blizzard UI code for determining level cap
MAX_PLAYER_LEVEL_TABLE = {};
MAX_PLAYER_LEVEL_TABLE[0] = 60;
MAX_PLAYER_LEVEL_TABLE[1] = 70;
MAX_PLAYER_LEVEL_TABLE[2] = 80;
MAX_PLAYER_LEVEL = 0;
MAX_PLAYER_LEVEL = MAX_PLAYER_LEVEL_TABLE[GetAccountExpansionLevel()];
GetAchievementCategory
Returns the numeric ID of the category to which an achievement belongs.
categoryID = GetAchievementCategory(achievementID)
Chapter 27 API Reference 641
Arguments:
achievementIDThe numeric ID of an achievement (number)
Returns:
categoryIDThe numeric ID of the achievement’s category (number)
GetAchievementComparisonInfo
Returns information about the comparison unit’s achievements.
completed, month, day, year = GetAchievementComparisonInfo(id)
Only accurate once the INSPECT_ACHIEVEMENT_READY event has fired
following a call to SetAchievementComparisonUnit(). No longer accurate
once ClearAchievementComparisonUnit() is called.
Arguments:
idThe numeric ID of an achievement (number)
Returns:
completedTrue if the comparison unit has completed the achievement;
otherwise nil (boolean)
monthMonth in which the comparison unit completed the achievement
(number)
dayDay of the month on which the comparison unit completed the achieve-
ment (number)
yearYear in which the comparison unit completed the achievement.
(Two-digit year, assumed to be 21st century.) (number)
GetAchievementCriteriaInfo
Gets information about criteria for an achievement or data for a statistic.
description, type, completed, quantity, requiredQuantity, i
characterName, flags, assetID, quantityString, criteriaID = i
GetAchievementCriteriaInfo(achievementID, index) or i
GetAchievementCriteriaInfo(statisticID)
Arguments:
achievementIDThe numeric ID of an achievement (number)
indexIndex of one of the achievement’s criteria (between 1and
GetAchievementNumCriteria()) (number)
statisticIDThe numeric ID of a statistic (number)
Returns:
descriptionDescription of the criterion (as displayed in the UI
for achievements with multiple criteria) or statistic (string)
typeType of criterion: a value of 8 indicates the criterion is another
achievement; other values are not used in the default UI (number)
completedTrue if the player has completed the criterion; otherwise false
(boolean)
642 Part IV Reference
quantityIf applicable, number of steps taken towards completing the
criterion (e.g. for the only criterion of ‘‘Did Somebody Order a Knuckle
Sandwich?‘‘, the player’s current Unarmed skill; for the first criterion of
‘‘Pest Control‘‘, 1if the player has killed an Adder, 0 otherwise (number)
requiredQuantityIf applicable, number of steps required to complete
the criterion (e.g. 400 for the only criterion of ‘‘Did Somebody Order a
Knuckle Sandwich?‘‘; 1for any criterion of ‘‘Pest Control’’ (number)
characterNameCharacter name with which the criterion was completed.
Currently always the player character’s name for completed criteria (string)
flagsTest against the following masks with bit.band() to reveal additional
information: (bitfield)
0x00000001Criterion should be displayed as a progress bar
0x00000002Criterion should be hidden in normal achievement displays
assetIDInternal ID number of the quest to complete, NPC to kill, item
to acquire, world object to interact with, achievement to earn, or other
game entity related to completing the criterion. (Note: some but not all
of these ID types are usable elsewhere in the WoW API) (number)
quantityStringText to be shown when displaying quantity and
requiredQuantity in a UI element. (Not always the same as format(“%d /
%d“, quantity, requiredQuantity); e.g. ‘‘Got My Mind On My Money’’
shows monetary amounts with embedded textures for gold, silver, and copper)
(string)
criteriaIDUnique ID number identifying the criterion; usable with
GetAchievementInfoFromCriteria() (number)
GetAchievementInfo
Gets information about an achievement or statistic.
id, name, points, completed, month, day, year, description, flags, i
icon, rewardText = GetAchievementInfo(category, index) or i
GetAchievementInfo(id)
Arguments:
categoryNumeric ID of an achievement category (number)
indexIndex of an achievement within a category (between 1and GetCatego-
ryNumAchievements()) (number)
idThe numeric ID of an achievement or statistic (number)
Returns:
idThe numeric ID of the achievement or statistic (number)
nameName of the achievement or statistic (string)
pointsAmount of achievement points awarded for completing the achieve-
ment (number)
completedTrue if the player has completed the achievement; otherwise
false (boolean)
monthMonth in which the player completed the achievement (number)
Chapter 27 API Reference 643
dayDay of the month on which the player completed the achievement
(number)
yearYear in which the player completed the achievement. (Two-digit year,
assumed to be 21st century.) (number)
descriptionDescription of the achievement (string)
flagsTest against the following masks with bit.band() to reveal additional
information: (bitfield)
0x00000001Info is for a statistic, not an achievement
0x00000002Achievement should be hidden in normal displays
0x00000080Achievement should display its criteria as a progress bar
regardless of per-criterion flags
iconPath to an icon texture for the achievement (string)
rewardTextText describing a reward for the achievement, or the empty string
if no reward is offered (string)
GetAchievementInfoFromCriteria
Gets information about an achievement or statistic given a criterion ID.
id, name, points, description, flags, icon, rewardText = i
GetAchievementInfoFromCriteria(id)
Arguments:
idThe numeric ID of an achievement or statistic criterion (as can
be retrieved from GetAchievementCriteriaInfo()) (number)
Returns:
idThe numeric ID of the achievement or statistic (number)
nameName of the achievement or statistic (string)
pointsAmount of achievement points awarded for completing the achieve-
ment (number)
descriptionDescription of the achievement (string)
flagsTest against the following masks with bit.band() to reveal additional
information: (bitfield)
0x00000001Info is for a statistic, not an achievement
0x00000002Achievement should be hidden in normal displays
0x00000080Achievement should display its criteria as a progress bar
regardless of per-criterion flags
iconPath to an icon texture for the achievement (string)
rewardTextText describing a reward for the achievement, or the empty string
if no reward is offered (string)
GetAchievementLink
Returns a hyperlink representing the player’s progress on an achievement.
link = GetAchievementLink(id)
644 Part IV Reference
The tooltip associated with the hyperlink shows not only the details of
the achievement itself, but also the completion of or progress towards the
achievement by the player who produced the link.
Arguments:
idThe numeric ID of an achievement (number)
Returns:
linkA hyperlink for the player’s achievement (string)
GetAchievementNumCriteria
Returns the number of measured criteria for an achievement.
count = GetAchievementNumCriteria(id)
Measured criteria for an achievement are shown in the default UI as details
when clicking on an achievement in the achievements window or when
showing an achievement in the objectives tracker; e.g. ‘‘Master of Arms’’ (15
criteria: Axes, Bows, Crossbows, Daggers, etc.) and ‘‘Safe Deposit’’ (1 criterion:
number of bank slots purchased).
Not all achievements have criteria: achievements with zero criteria are those
that can be completed in a single event (though a complicated event it may be),
explained in achievement’s description: e.g. ‘‘Reach level 80‘‘, ‘‘Fall 65 yards
without dying‘‘, and ‘‘With all three Twilight Drakes still alive, engage and
defeat Sartharion the Onyx Guardian on Normal Difficulty‘‘.
Arguments:
idThe numeric ID of an achievement (number)
Returns:
countNumber of criteria for the achievement (number)
GetAchievementNumRewards
Returns the number of point rewards for an achievement (currently always 1).
count = GetAchievementNumRewards(id)
Currently all achievements and statistics offer one reward (according to this
function), though the rewards offered by statistics are all zero points.
Arguments:
idThe numeric ID of an achievement or statistic (number)
Returns:
countNumber of point rewards offered for the achievement (number)
GetAchievementReward
Returns the number of achievement points awarded for earning an
achievement.
points = GetAchievementReward(id, index)
Currently all achievements and statistics offer one reward (according to this
function), though the rewards offered by statistics are all zero points.
Chapter 27 API Reference 645
Arguments:
idThe numeric ID of an achievement or statistic (number)
indexIndex of one of the achievement’s rewards (between 1and
GetAchievementNumRewards(); currently always 1) (number)
Returns:
pointsNumber of achievement points awarded for completing the achieve-
ment (number)
GetActionBarPage
Returns the current action bar page.
page = GetActionBarPage()
Returns:
pageThe current action bar page (number)
GetActionBarToggles
Returns the current visibility settings for the four secondary action bars.
showBar1, showBar2, showBar3, showBar4 = GetActionBarToggles()
Returns:
showBar11if the interface option is set to show the Bottom Left ActionBar,
otherwise nil (1nil)
showBar21if the interface option is set to show the Bottom Right ActionBar,
otherwise nil (1nil)
showBar31if the interface option is set to show the Right ActionBar, other-
wise nil (1nil)
showBar41if the interface option is set to show the Right ActionBar 2, other-
wise nil (1nil)
GetActionCooldown
Returns cooldown information about an action.
start, duration, enable = GetActionCooldown(slot)
Arguments:
slotAn action bar slot (number,actionID)
Returns:
start—The value of GetTime() at the moment the cooldown began, or 0 if the
action is ready (number)
durationThe length of the cooldown, or 0 if the action is ready (number)
enable1if a Cooldown UI element should be used to display the cooldown,
otherwise 0. (Does not always correlate with whether the action is ready.)
(number)
Example:
-- Show all actions currently on cooldown
for i=1,120 do
local start,duration,enable = GetActionCooldown(i)
if start > 0 and enable == 1 then
646 Part IV Reference
local actiontype,id,subtype = GetActionInfo(i)
local name
if actiontype == “spell“ then
name = GetSpellName(id, “spell“)
elseif actiontype == “item“ then
name = GetItemInfo(id)
elseif actiontype == “companion“ then
name = select(2, GetCompanionInfo(subtype, id))
end
local timeLeft = math.floor((start + duration) - GetTime())
local output = string.format(“Cooldown on %s %s i
(%s seconds left)“, actiontype, name, timeLeft)
ChatFrame1:AddMessage(output)
end
end
GetActionCount
Returns the number of uses remaining for the given action slot.
count = GetActionCount(slot)
Applies to spells that require reagents, items that stack, or items with charges;
used in the default UI to display the count on action buttons.
Returns 0 for any action that does not use a count. To distinguish between
actions which do not use a count and actions which do but whose current
count is 0, see IsConsumableAction.
Arguments:
slotAn action bar slot (number,actionID)
Returns:
countNumber of times the action can be used (number)
GetActionInfo
Returns information about an action slot.
type, id, subType, spellID = GetActionInfo(slot)
Arguments:
slotAn action slot (number)
Returns:
typeTypeofactionintheslot(string)
companionSummons a mount or non-combat pet
equipmentset—Equips a set of items
item—Uses an item
macro—Runs a macro
spellCasts a spell
Chapter 27 API Reference 647
idAn identifier for the action; varies by type: (number or string)
companionThe companion’s index in the mount or minipet list
equipmentsetName of the equipment set
itemThe item’s itemID
macroThe macro’s index in the macro list (macroID)
spellThe spell’s index in the player’s spellbook (spellbookID)
subTypeSubtype of the action (or nil if not applicable) (string)
CRITTER—For companion actions: indicates id is as an index in the
non-combat pets list
MOUNT—For companion actions: indicates id is an index in the mounts list
spell—For spell actions: indicates id is an index in the player’s spellbook
(as opposed to the pet’s)
spellID—For spell and companion actions, the global ID of the spell
(or the summoning ‘‘spell’’ for a companion) (string, spellID)
Example:
-- Prints all types and subtypes found in the player’s actions
local types = {}
for i=1,120 do
local type,id,subtype = GetActionInfo(i)
if type then
types[type] = types[type] or {}
if subtype then
types[type][subtype] = 1
end
end
end
for type, subtypes in pairs(types) do
print(“Type:“, type, “subtypes:“)
local numSubtypes = 0
for subtype in pairs(subtypes) do
print(“ “, subtype)
numSubtypes = numSubtypes + 1
end
if numSubtypes == 0 then
print(“ no subtypes“)
end
end
GetActionText
Returns the text label associated with an action.
text = GetActionText(slot)
Currently used only for macros, which in the default UI show their name as a
labelonanactionbutton.
648 Part IV Reference
Arguments:
slotAn action bar slot (number,actionID)
Returns:
textLabel for the action (string)
GetActionTexture
Returns the icon texture for an action.
texture = GetActionTexture(slot)
Can be the icon of a spell or item, the icon manually set for a macro, or an icon
reflecting the current state of a macro.
Arguments:
slotAn action bar slot (number,actionID)
Returns:
texturePath to an icon texture for the action in the slot, or nil if the slot is
empty (string)
GetActiveLevel
Returns the level of a quest which can be turned in to the current Quest NPC.
level = GetActiveLevel(index)
Only returns valid information after a QUEST_GREETING event.
Note: Most quest NPCs present active quests using the
GetGossipActiveQuests() instead of this function.
Arguments:
indexIndex of a quest which can be turned in to the current
Quest NPC (between 1and GetNumActiveQuests())(number)
Returns:
levelRecommended character level for attempting the quest (number)
GetActiveTalentGroup
Returns the index of the active talent specialization.
activeTalentGroup = GetActiveTalentGroup(isInspect, isPet)
Arguments:
isInspecttrue to query talent info for the currently inspected unit, false to
query talent info for the player (boolean)
isPettrue to query talent info for the player’s pet, false to query talent info
for the player (boolean)
Returns:
activeTalentGroupWhich talent group is currently active (number)
1Primary Talents
2—Secondary Talents
GetActiveTitle
Returns the name of a quest which can be turned in to the current Quest NPC.
title = GetActiveTitle(index)
Chapter 27 API Reference 649
Only returns valid information after a QUEST_GREETING event.
Note: Most quest NPCs present active quests using the GetGossipActive
Quests() instead of this function.
Arguments:
indexIndex of a quest which can be turned in to the current Quest NPC
(between 1and GetNumActiveQuests())(number)
Returns:
titleTitle of the quest (string)
GetActiveVoiceChannel
Returns the currently active voice channel.
index = GetActiveVoiceChannel()
Returns:
indexIndex of the active voice channel in the chat display window (between
1and GetNumDisplayChannels()), or nil if no channel is active (number)
GetAddOnCPUUsage
Returns the amount of CPU time used by an addon.
usage = GetAddOnCPUUsage(“name“) or GetAddOnCPUUsage(index)
Only returns valid data if the scriptProfile CVar is set to 1; returns 0
otherwise.
The value returned is from a cache only updated when calling UpdateAddOn
CPUUsage(). This value is the sum of GetFunctionCPUUsage() for all
functions created on the addon’s behalf. Note that if the addon calls external
functions which in turn create new functions, the new functions are considered
to belong to the addon.
Arguments:
nameName of an addon (name of the addon’s folder and TOC file, not the Title
found in the TOC) (string)
indexIndex of an addon in the addon list (between 1and GetNumAddOns())
(number)
Returns:
usageAmount of CPU time used by the addon (in milliseconds) since
the UI was loaded or ResetCPUUsage() was last called (number)
GetAddOnDependencies
Returns a list of addons a given addon is dependent upon.
... = GetAddOnDependencies(“name“) or GetAddOnDependencies(index)
Arguments:
nameName of an addon (name of the addon’s folder and TOC file, not the Title
found in the TOC) (string)
indexIndex of an addon in the addon list (between 1and GetNumAddOns())
(number)
650 Part IV Reference
Returns:
...A list of strings, each the (folder) name of another addon this addon is
dependent upon (list)
GetAddOnInfo
Returns information about an addon.
name, title, notes, enabled, loadable, reason, security = i
GetAddOnInfo(“name“) or GetAddOnInfo(index)
Arguments:
nameName of an addon (name of the addon’s folder and TOC file, not the Title
found in the TOC) (string)
indexIndex of an addon in the addon list (between 1and GetNumAddOns())
(number)
Returns:
nameName of the addon (name of the addon’s folder and TOC file) (string)
titleTitle of the addon (from the Title header in the addon’s TOC file)
(string)
notesContents of the Notes header in the addon’s TOC file (string)
enabled1if the addon is enabled; otherwise nil (1nil)
loadableIf the addon can currently be loaded (1nil)
reasonIf the addon cannot be loaded, an unlocalized string token indicating
the reason for failure. Localized strings for display can be found by prepending
“ADDON_“;e.g.ADDON_DEP_MISSING == “Dependency missing“.(string)
BANNEDBanned
CORRUPTCorrupt
DEP_BANNEDDependency banned
DEP_CORRUPTDependency corrupt
DEP_DISABLEDDependency disabled
DEP_INCOMPATIBLEDependency incompatible
DEP_INSECUREDependency insecure
DEP_INTERFACE_VERSIONDependency out of date
DEP_MISSINGDependency missing
DEP_NOT_DEMAND_LOADEDDependency not loadable on demand
DISABLEDDisabled
INCOMPATIBLE—Incompatible
INSECURE—Insecure
INTERFACE_VERSION—Out of Date
MISSINGMissing
NOT_DEMAND_LOADEDNot loadable on demand
security“SECURE“ for Blizzard built-in addons (or other digitally
signed Blizzard-produced addons); otherwise “INSECURE“ (string)
Chapter 27 API Reference 651
GetAddOnMemoryUsage
Returns the amount of memory used by an addon.
mem = GetAddOnMemoryUsage(“name“) or GetAddOnMemoryUsage(index)
The value returned is from a cache only updated when calling
UpdateAddOnMemoryUsage().
Arguments:
nameName of an addon (name of the addon’s folder and TOC file, not the Title
found in the TOC) (string)
indexIndex of an addon in the addon list (between 1and GetNumAddOns())
(number)
Returns:
memMemory usage of the addon (in kilobytes) (number)
GetAddOnMetadata
Returns the value of certain fields in an addon’s TOC file.
data = GetAddOnMetadata(“name“, “header“) or i
GetAddOnMetadata(index, “header“)
Arguments:
nameName of an addon (name of the addon’s folder and TOC file, not the Title
found in the TOC) (string)
indexIndex of an addon in the addon list (between 1and GetNumAddOns())
(number)
headerName of a header from the addon’s TOC file; only certain
headers can be queried: Author,Title,Notes,Version,andanyheader
whosenamestartswith“X-“ (e.g. X-Website,X-Category)(string)
Returns:
dataContents of the given TOC file header, or nil if the header does not exist
or cannot be queried (string)
GetAreaSpiritHealerTime
Returns the time remaining until a nearby battleground spirit healer resurrects
all players in its area.
timeleft = GetAreaSpiritHealerTime()
Returns:
timeleftSeconds remaining before the next area resurrection (number)
GetArenaCurrency
Returns the player’s amount of arena points.
points = GetArenaCurrency()
Returns:
pointsThe player’s current amount of honor points (number)
652 Part IV Reference
GetArenaTeam
Returns information about one of the player’s arena teams.
teamName, teamSize, teamRating, teamPlayed, teamWins, i
seasonTeamPlayed, seasonTeamWins, playerPlayed, seasonPlayerPlayed, i
teamRank, playerRating, bg_red, bg_green, bg_blue, emblem, i
emblem_red, emblem_green, emblem_blue, border, border_red, i
border_green, border_blue = GetArenaTeam(team)
Arguments:
teamIndex of one of the player’s arena teams (number,arenaTeamID)
Returns:
teamNameName of the arena team (string)
teamSizeSize of the team (2 for 2v2, 3 for 3v3, or 5 for 5v5) (number)
teamRatingThe team’s current rating (number)
teamPlayedNumber of games played by the team in the current week
(number)
teamWinsNumber of games won by the team in the current week (number)
seasonTeamPlayedNumber of games played by the team in the current arena
season (number)
seasonTeamWinsNumber of games won by the team in the current arena sea-
son (number)
playerPlayedNumber of games in which the player has participated in the
current week (number)
seasonPlayerPlayedNumber of games in which the player has participated
in the current arena season (number)
teamRankThe team’s current rank among same-size teams in its battlegroup
(number)
playerRatingThe player’s personal rating with this team (number)
bg_redRed component of the color value for the team banner’s background
(number)
bg_greenGreen component of the color value for the team banner’s back-
ground (number)
bg_blueBlue component of the color value for the team banner’s background
(number)
emblemIndex of the team’s emblem graphic; full path to the emblem texture
can be found using the format “Interface\PVPFrame\Icons\PVP-Banner-
Emblem-“..emblem (number)
emblem_redRed component of the color value for the team banner’s emblem
(number)
emblem_greenGreen component of the color value for the team banner’s
emblem (number)
emblem_blueBlue component of the color value for the team banner’s
emblem (number)
Chapter 27 API Reference 653
borderIndex of the team’s border graphic; full path to the border texture
can be found by using the format “Interface\PVPFrame\PVP-Banner-“..
teamSize..“-Border-“..border (number)
border_redRed component of the color value for the team banner’s border
(number)
border_greenGreen component of the color value for the team banner’s bor-
der (number)
border_blueBlue component of the color value for the team banner’s border
(number)
GetArenaTeamRosterInfo
Returns information about an arena team member.
name, rank, level, class, online, played, win, seasonPlayed, i
seasonWin, rating = GetArenaTeamRosterInfo(team, index)
Arguments:
teamIndex of one of the player’s arena teams (number,arenaTeamID)
indexIndex of a team member (between 1and GetNumArenaTeamMembers
(team))(number)
Returns:
nameName of the team member (string)
rankRank of the member in the team (number)
0—Team captain
1—Member
levelCharacter level of the team member (number)
classLocalized name of the team member’s class (string)
online1if the team member is currently online; otherwise nil (1nil)
playedNumber of games played by the team member in the current week
(number)
winNumber of winning games played by the team member in the current
week (number)
seasonPlayedNumber of games played by the team member in the current
arena season (number)
seasonWinNumber of winning games played by the team member in the cur-
rent arena season (number)
ratingThe team member’s personal rating with this team (number)
GetArenaTeamRosterSelection
Returns the currently selected member in an arena team roster.
index = GetArenaTeamRosterSelection(team)
Selection in the arena team roster currently has no effect beyond highlighting
list entry in the default UI.
Arguments:
teamIndex of one of the player’s arena teams (number,arenaTeamID)
654 Part IV Reference
Returns:
indexIndex of the selected member in the roster listing (number)
GetArmorPenetration
Returns the percentage of enemy armor ignored due to the player’s Armor
Penetration Rating.
amount = GetArmorPenetration()
Returns:
amountPercentage of enemy armor ignored due to the player’s Armor Pene-
tration Rating (number)
GetAttackPowerForStat
Returns the attack power bonus provided by one of the player’s basic statistics.
attackPower = GetAttackPowerForStat(statIndex, effectiveStat)
Arguments:
statIndexIndex of a basic statistic (number)
1—Strength
2Agility
3—Stamina
4Intellect
5—Spirit
effectiveStatValue of the statistic to use in attack power calculation
(number)
Returns:
attackPowerAttack power bonus provided to the player by the basic statistic
value (number)
GetAuctionInvTypes
Returns a list of the inventory subtypes for a given auction house item
subclass.
token, display, ... = GetAuctionInvTypes(classIndex, subClassIndex)
Inventory types are the second level of hierarchy seen when browsing item
classes (categories) and subclasses at the Auction House: Head,Neck,Shirt,et
al for Miscellaneous;Head,Shoulder,Chest,Wrist,etalforCloth;etc.
This function still returns valid information if the player is not interacting with
an auctioneer.
Arguments:
classIndexIndex of an item class (in the list returned by GetAuctionItem
Classes()); currently, inventory types are only applicable in class 2(armor)
(number)
subClassIndexIndex of an item subclass (in the list returned by
GetAuctionItemSubClasses(classIndex)); currently, inventory types
are only applicable in the armor subclasses listed below: (number)
1Miscellaneous
2—Cloth
3Leather
4—Mail
5—Plate
Chapter 27 API Reference 655
Returns:
tokenName of a global variable containing the localized name of the inven-
tory type (e.g. INVTYPE_FINGER)(string)
display1if the inventory type should be displayed; otherwise nil
(used in the default auction UI to hide subclass/invType combinations that
don’t exist in the game; e.g. Plate/Back, Leather/Trinket, etc) (1nil)
...Additional token, display pairs for each inventory type listed (list)
GetAuctionItemClasses
Returns a list of localized item class (category) names.
... = GetAuctionItemClasses()
Item classes are the first level of hierarchy seen when browsing at the Auction
House: Weapon,Armor,Container,Consumable,etc.
This function still returns valid information if the player is not interacting with
an auctioneer.
Returns:
...A list of strings, each the name of an item class (list)
Example:
-- prints the list of item classes
print(GetAuctionItemClasses())
GetAuctionItemInfo
Returns information about an auction listing.
name, texture, count, quality, canUse, level, minBid, minIncrement, i
buyoutPrice, bidAmount, highestBidder, owner, sold = i
GetAuctionItemInfo(“list“, index)
Arguments:
listType of auction listing (string)
bidderAuctions the player has bid on
listAuctions the player can browse and bid on or buy out
ownerAuctions the player placed
indexIndex of an auction in the listing (number)
Returns:
name—Name of the item (string)
texturePathtoanicontexturefortheitem(string)
countNumber of items in the stack (number)
qualityThe quality (rarity) level of the item (number, itemQuality)
canUse1if the player character can use or equip the item; otherwise nil
(1nil)
levelRequired character level to use or equip the item (number)
minBidMinimum cost to bid on the item (in copper) (number)
minIncrementMinimum bid increment to become the highest bidder on the
item (in copper) (number)
656 Part IV Reference
buyoutPriceBuyout price of the auction (in copper) (number)
bidAmountCurrent highest bid on the item (in copper); 0 if no bids have been
placed (number)
highestBidder1if the player is currently the highest bidder; otherwise nil
(1nil)
ownerName of the character who placed the auction (string)
sold1if the auction has sold (and payment is awaiting delivery; applies only
to owner auctions); otherwise nil (number)
GetAuctionItemLink
Returns a hyperlink for an item in an auction listing.
link = GetAuctionItemLink(“list“, index)
Arguments:
listType of auction listing (string)
bidderAuctions the player has bid on
listAuctions the player can browse and bid on or buy out
ownerAuctions the player placed
indexIndex of an auction in the listing (number)
Returns:
linkA hyperlink for the item (string, hyperlink)
GetAuctionItemSubClasses
Returns a list of localized subclass names for a given item class.
... = GetAuctionItemSubClasses(classIndex)
Item subclasses are the second level of hierarchy seen when browsing item
classes (categories) at the Auction House: One-Handed Axes,Two-Handed
Axes,Bows,Guns,etalforWeapon;Cloth,Leather,Plate,Shields,etalfor
Armor;Food & Drink,Potion,Elixir et al for Consumable;Red,Blue,
Yellow,etalforGem;etc.
This function still returns valid information if the player is not interacting with
an auctioneer.
Arguments:
classIndexIndex of an item class (in the list returned by GetAuctionItem
Classes())(number)
Returns:
...A list of strings, each the name of an item subclass; or nil if the class con-
tains no subclasses (list)
Example:
-- prints a list of the subclasses for each item class
function printSubClasses(...)
for class = 1, select(“#“, ...) do
print(select(class, ...).. “:“, strjoin(“, “, i
GetAuctionItemSubClasses(class)))
Chapter 27 API Reference 657
end
end
printSubClasses(GetAuctionItemClasses())
GetAuctionItemTimeLeft
Returns the time remaining before an auction listing expires.
duration = GetAuctionItemTimeLeft(“list“, index)
Arguments:
listType of auction listing (string)
bidderAuctions the player has bid on
listAuctions the player can browse and bid on or buy out
ownerAuctions the player placed
indexIndex of an auction in the listing (number)
Returns:
durationGeneral indication of the amount of time remaining on the auction
(number)
1Short (less than 30 minutes)
2Medium (30 minutes to 2 hours)
3Long (2 hours to 12 hours)
4Very Long (more than 12 hours)
GetAuctionSellItemInfo
Returns information about the item currently being set up for auction.
name, texture, count, quality, canUse, price = GetAuctionSellItemInfo()
Only returns useful information once an item has been placed in the Create
Auction UI’s ‘‘auction item’’ slot (see ClickAuctionSellItemButton()).
Returns:
name—Name of the item (string)
texturePathtoanicontexturefortheitem(string)
countNumber of items in the stack (number)
qualityQuality (rarity) level of the item (number, itemQuality)
canUse1if the player character can use or equip the item; otherwise nil
(1nil)
pricePrice to sell the item to a vendor (in copper) (number)
GetAuctionSort
Returns the current sort settings for auction data.
criterion, reverse = GetAuctionSort(“list“, index)
The index argument describes priority order for sort criteria: e.g. if
GetAuctionSort(“list“,1) returns quality and
GetAuctionSort(“list“,2) returns level,1, items are sorted first by
itemQuality and items with the same quality are sorted by required level.
658 Part IV Reference
Arguments:
listType of auction listing (string)
bidderAuctions the player has bid on
listAuctions the player can browse and bid on or buy out
ownerAuctions the player placed
indexIndex of a sorting priority (number)
Returns:
criterionNon-localized string naming the criterion (or column in the
default UI) by which listings are sorted (string)
reverse1if listings are sorted in reverse order; otherwise nil.
‘‘Reverse’’ here is relative to the default order, not to absolute value:
e.g. the default order for quality is descending (Epic, Rare, Uncommon,
etc), but the default order for level is ascending (180) (1nil)
GetAutoCompleteResults
Returns a list of character names which complete a given partial name prefix.
... = GetAutoCompleteResults(“inputString“, includeBitfield, i
excludeBitfield, maxResults [, cursorPosition])
Arguments:
inputStringPartial name for which to return completions (string)
includeBitfieldOne or more of the following flags (combined via
bit.bor()), indicating which characters should be included in the result list:
(number, bitfield)
0x00000000AUTOCOMPLETE_FLAG_NONE:Nocharacters
0x00000001AUTOCOMPLETE_FLAG_IN_GROUP: Characters in the player’s
party or raid
0x00000002AUTOCOMPLETE_FLAG_IN_GUILD: Characters in the player’s
guild
0x00000004AUTOCOMPLETE_FLAG_FRIEND: Characters from the player’s
friends list
0x00000010AUTOCOMPLETE_FLAG_INTERACTED_WITH:Characterswith
whom the player has recently interacted
0x00000020AUTOCOMPLETE_FLAG_ONLINE: Currently online friends and
guildmates
0xffffffffAUTOCOMPLETE_FLAG_ALL: All characters
excludeBitfieldOne or more of the following flags (combined via
bit.bor()), indicating which characters should be excluded from the result list:
(number, bitfield)
0x00000000AUTOCOMPLETE_FLAG_NONE:Nocharacters
0x00000001AUTOCOMPLETE_FLAG_IN_GROUP: Characters in the player’s
party or raid
0x00000002AUTOCOMPLETE_FLAG_IN_GUILD: Characters in the player’s
guild
Chapter 27 API Reference 659
0x00000004AUTOCOMPLETE_FLAG_FRIEND: Characters from the player’s
friends list
0x00000010AUTOCOMPLETE_FLAG_INTERACTED_WITH:Characterswith
whom the player has recently interacted
0x00000020AUTOCOMPLETE_FLAG_ONLINE: Currently online friends and
guildmates
0xffffffffAUTOCOMPLETE_FLAG_ALL: All characters
maxResultsMaximum number of results to be returned (number)
cursorPosition (optional)Cursor position in the inputString; currently
unused (number)
Returns:
...A list of strings, each the name of a character matching the search parame-
ters (list)
Example:
-- prints up to 10 names of friends and guild members starting with “G“
print(GetAutoCompleteResults(“g“, i
bit.bor(AUTOCOMPLETE_FLAG_IN_GUILD,
AUTOCOMPLETE_FLAG_FRIEND), AUTOCOMPLETE_FLAG_NONE, 10))
-- prints up to 10 names of guild members not on the friends list
-- starting with “G“
print(GetAutoCompleteResults(“g“, AUTOCOMPLETE_FLAG_IN_GUILD, i
AUTOCOMPLETE_FLAG_FRIEND, 10))
GetAvailableLevel
Returns the level of a quest available from the current Quest NPC.
level = GetAvailableLevel(index)
Only returns valid information after a QUEST_GREETING event.
Note: Most quest NPCs present available quests using the
GetGossipAvailableQuests() instead of this function.
Arguments:
indexIndex of a quest available from the current Quest NPC (between 1and
GetNumAvailableQuests())(number)
Returns:
levelRecommended character level for attempting the quest (number)
GetAvailableTitle
Returns the name of a quest available from the current Quest NPC.
title = GetAvailableTitle(index)
Only returns valid information after a QUEST_GREETING event.
Note: Most quest NPCs present available quests using the GetGossip
AvailableQuests() instead of this function.
660 Part IV Reference
Arguments:
indexIndex of a quest available from the current Quest NPC (between 1and
GetNumAvailableQuests())(number)
Returns:
titleTitle of the quest (string)
GetBackpackCurrencyInfo
Returns information about a currency marked for watching on the Backpack
UI.
name, count, extraCurrencyType, icon, itemID = i
GetBackpackCurrencyInfo(index)
Arguments:
indexIndex of a slot for displaying currencies on the backpack (between 1
and MAX_WATCHED_TOKENS)(number)
Returns:
nameName of the currency type (string)
countAmount of the currency the player has (number)
extraCurrencyTypeType of the currency (number)
0Item-based currency
1—Arena points
2Honor points
iconPath to an icon texture representing the currency item (for
Honor/Arena points, not the icon displayed in the default UI) (string)
itemIDID for the currency item (number)
GetBagName
Returns the name of one of the player’s bags.
name = GetBagName(container)
Returns nil for the bank and keyring, for bank bags while the player is not at
the bank, and for empty bag or bank bag slots.
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
Returns:
nameName of the container (string)
Example:
-- Print the names of the player’s bags to chat
for i=0,4 do
local name = GetBagName(i)
if name then
print(“Bag“, i, “:“, name)
end
end
Chapter 27 API Reference 661
GetBankSlotCost
Returns the cost of the next purchasable bank bag slot.
cost = GetBankSlotCost()
Returns 999999999 if the player owns all available slots.
Returns:
costCost of the next available bank bag slot (in copper) (number)
GetBarberShopStyleInfo
Returns information about the selected barber shop style option.
name, unused, cost, isCurrent = GetBarberShopStyleInfo(styleIndex)
Arguments:
styleIndexIndex of a style option (number)
1—Hair (or Horn) Style
2Hair (or Horn) Color
3Varies by race and gender: Facial Hair, Earrings, Features, Hair, Horns,
Markings, Normal, Piercings, or Tusks
Returns:
nameName of the style option, or nil if the style is not named (string)
unusedCurrently unused (string)
costPrice of applying the style option, not including changes to other style
options (in copper) (number)
isCurrent1if the style option matches the character’s existing style; other-
wise nil (1nil)
GetBarberShopTotalCost
Returns the total price of selected barber shop style changes.
cost = GetBarberShopTotalCost()
Returns:
costPrice of the barber shop style change (in copper) (number)
GetBattlefieldEstimatedWaitTime
Returns the estimated wait time on a battleground or arena queue.
waitTime = GetBattlefieldEstimatedWaitTime(index)
Arguments:
indexIndex of a battleground/arena queue the player has joined (between 1
and MAX_BATTLEFIELD_QUEUES)(number)
Returns:
waitTimeEstimated wait time to join the battleground/arena (in millisec-
onds) (number)
GetBattlefieldFlagPosition
Returns the position of a flag in a battleground.
flagX, flagY, flagToken = GetBattlefieldFlagPosition(index)
662 Part IV Reference
Arguments:
indexIndex of a flag (between 1and GetNumBattlefieldFlag
Positions())(number)
Returns:
flagXHorizontal (X) coordinate of the flag’s position relative to the zone map
(0 =left edge, 1=right edge) (number)
flagYVertical (Y) coordinate of the flag’s position relative to the zone map
(0 =bottom edge, 1=top edge) (number)
flagTokenUnique portion of the path to a texture for the flag; preface
with “Interface\\WorldStateFrame\for the full path (string)
GetBattlefieldInfo
Returns information about a battleground for which the player can queue.
mapName, mapDescription, minLevel, maxLevel, bracketMin, bracketMax, i
maxGroup = GetBattlefieldInfo()
Returns:
mapNameLocalized name of the battleground (string)
mapDescriptionLocalized descriptive text about the battleground (string)
minLevelMinimum character level required to enter the battleground
(number)
maxLevelMaximum character level allowed in the battleground (number)
bracketMinLowest level of characters in the player’s level bracket for the
battleground (number)
bracketMaxHighest level of characters in the player’s level bracket for the
battleground (number)
maxGroupMaximum number of players allowed when joining the battle-
ground queue as a group (number)
GetBattlefieldInstanceExpiration
Returns the amount of time remaining before all players are removed from the
instance, if in a battleground instance where the match has completed.
timeLeft = GetBattlefieldInstanceExpiration()
Returns:
timeLeftAmount of time remaining (in milliseconds) before all players are
removed from the instance, if in a battleground instance where the match has
completed; otherwise 0. (number)
GetBattlefieldInstanceInfo
Returns a numeric ID for a battleground instance in the battleground queueing
list.
instanceID = GetBattlefieldInstanceInfo(index)
This number is seen in the instance names in said listings and elsewhere in the
Battlegrounds UI (e.g. the 13 in ‘‘You are eligible to enter Warsong
Gulch 13‘‘).
Chapter 27 API Reference 663
Arguments:
indexIndex in the battleground queue listing (1for the first avail-
able instance, or between 2 and GetNumBattlefields() for other instances)
(number)
Returns:
instanceIDNumeric ID of the battleground instance (number)
GetBattlefieldInstanceRunTime
Returns the amount of time since the current battleground instance opened.
time = GetBattlefieldInstanceRunTime()
Returns:
timeAmount of time since the current battleground instance opened (in mil-
liseconds) (number)
Example:
-- Print the current battleground time as a string
print(SecondsToTime(GetBattlefieldInstanceRunTime()/1000))
GetBattlefieldMapIconScale
Returns the scale to be used for displaying battleground map icons.
scale = GetBattlefieldMapIconScale()
Used in the default UI to determine the size of the point of interest icons
(towers, graveyards, etc.) on the zone map (the small battle minimap). The
default size of the icons is set by DEFAULT_POI_ICON_SIZE and the scale is
used to grow or shrink them depending on the size of the map.
Returns:
scaleScale factor for map icons (between 0 and 1) (number)
Example:
-- Set the size of an icon scaled by this value
local size = DEFAULT_POI_ICON_SIZE * GetBattlefieldMapIconScale()
icon:SetWidth(size)
icon:SetHeight(size)
GetBattlefieldPortExpiration
Returns the time left on a battleground or arena invitation.
expiration = GetBattlefieldPortExpiration(index)
Arguments:
indexIndex of a battleground/arena queue the player has joined (between 1
and MAX_BATTLEFIELD_QUEUES)(number)
Returns:
expirationTime remaining before the player’s invitation to enter the
battleground/arena expires (in seconds); 0 if the player has not yet been
invited to enter or is already in the battleground/arena instance (number)
664 Part IV Reference
Example:
-- Print the time left for all active battleground queues
for index=1, MAX_BATTLEFIELD_QUEUES do
local status, name = GetBattlefieldStatus(index)
if status == “confirm“ then
print(format(
“Your invitation to %s will expire in %d seconds.“,
name, GetBattlefieldPortExpiration(index)
))
end
end
GetBattlefieldPosition
Returns the position of a battleground team member not in the player’s group.
unitX, unitY, name = GetBattlefieldPosition(index)
Still used in the default UI but no longer useful; as all team members in a
battleground match are automatically joined into a raid group. See GetPlayer
MapPosition() instead.
Arguments:
indexIndex of a team member (between 1and GetNumBattlefield
Positions())(number)
Returns:
unitXHorizontal (X) coordinate of the unit’s position relative to the zone map
(0 =left edge, 1=right edge) (number)
unitYVertical (Y) coordinate of the unit’s position relative to the zone map
(0 =bottom edge, 1=top edge) (number)
nameName of the unit for display on the map (string)
GetBattlefieldScore
Returns basic scoreboard information for a battleground/arena participant.
name, killingBlows, honorableKills, deaths, honorGained, faction, i
rank, race, classToken, damageDone, healingDone = i
GetBattlefieldScore(index)
Does not include battleground-specific score data (e.g. flags captured in
Warsong Gulch, towers assaulted in Alterac Valley, etc); see GetBattle
fieldStatData() for such information.
Arguments:
indexIndex of a participant in the battleground/arena scoreboard
(between 1and GetNumBattlefieldScores())(number)
Returns:
nameName of the participant (string)
killingBlowsNumber of killing blows scored by the participant during the
match (number)
Chapter 27 API Reference 665
honorableKillsNumber of honorable kills scored by the participant during
the match (number)
deathsNumber of times the participant died during the match (number)
honorGainedAmount of honor points gained by the participant during the
match (number)
factionFaction or team to which the participant belongs (number)
0Horde (Battleground) / Green Team (Arena)
1Alliance (Battleground) / Gold Team (Arena)
rankDeprecated; always 0 (number)
raceLocalized name of the participant’s race (string)
classTokenNon-localized token representing the participant’s class (string)
damageDoneTotal amount of damage done by the participant during the
match (number)
healingDoneTotal amount of healing done by the participant during the
match (number)
GetBattlefieldStatData
Returns battleground-specific scoreboard information for a battleground
participant.
columnData = GetBattlefieldStatData(index, statIndex)
Battleground-specific statistics include flags captured in Warsong Gulch,
towers assaulted in Alterac Valley, etc. For the name and icon associated with
each statistic, see GetBattlefieldStatInfo(). For basic battleground score
information, see GetBattlefieldScore().
Arguments:
indexIndex of a participant in the battleground/arena scoreboard
(between 1and GetNumBattlefieldScores())(number)
statIndexIndex of a battleground-specific statistic (between 1and
GetNumBattlefieldStats())(number)
Returns:
columnDataThe participant’s score for the statistic (number)
Example:
-- Print out the player’s battleground statistics
local playerName = UnitName(“player“)
for playerIndex = 1, GetNumBattlefieldStats() do
local name = GetBattlefieldScore(playerIndex)
if name == playerName then
local output = “Battleground stats for “..name..“:\n“
for statIndex = 1, GetNumBattlefieldStats() do
output = output .. “ “ .. GetBattlefieldStatInfo(statIndex) i
.. “: “ ..GetBattlefieldStatData(statIndex) .. “\n“
end
print(output)
666 Part IV Reference
break
end
end
GetBattlefieldStatInfo
Returns information about a battleground-specific scoreboard column.
text, icon, tooltip = GetBattlefieldStatInfo(statIndex)
Battleground-specific statistics include flags captured in Warsong Gulch,
towers assaulted in Alterac Valley, etc.
Arguments:
statIndexIndex of a battleground-specific statistic (between 1and
GetNumBattlefieldStats())(number)
Returns:
textName to display for the statistic’s scoreboard column header (string)
iconPath to an icon texture for the statistic (string)
tooltipText to be displayed as a tooltip when mousing over the scoreboard
column (string)
GetBattlefieldStatus
Returns information about an active or queued battleground/arena instance.
status, mapName, instanceID, bracketMin, bracketMax, teamSize, i
registeredMatch = GetBattlefieldStatus(index)
Arguments:
indexIndex of a battleground/arena queue the player has joined (between 1
and MAX_BATTLEFIELD_QUEUES)(number)
Returns:
statusStatus of the player with respect to the battleground (string)
activeThe player is currently playing in this battleground
confirmThe player has been invited to enter this battleground but has not
done so yet
noneNo battleground or queue at this index
queuedThe player is queued for this battleground
mapNameName of the battleground (e.g. ‘‘Alterac Valley‘‘) or arena (‘‘All
Arenas’’ while queued; ‘‘Eastern Kingdoms’’ regardless of destination
while status is confirm, e.g. ‘‘Dalaran Sewers’’ while active)(string)
instanceIDIf in a battleground or queued for a specific instance, the
number identifying that instance (e.g. 13 in ‘‘Warsong Gulch 13‘‘); otherwise 0
(number)
bracketMinLowest level of characters in the player’s level bracket for the
battleground (number)
bracketMaxHighest level of characters in the player’s level bracket for the
battleground (number)
Chapter 27 API Reference 667
teamSizeNumber of players per team for an arena match (number)
0Not an arena match
2—2v2 Arena
3—3v3 Arena
5—5v5 Arena
registeredMatch1if a rated arena match; otherwise nil (1nil)
GetBattlefieldTeamInfo
Returns info about teams and their ratings in a rated arena match.
teamName, teamRating, newTeamRating = GetBattlefieldTeamInfo(index)
Usable following the UPDATE_BATTLEFIELD_SCORE event.
Arguments:
indexIndex of a team in the arena match (number)
0Green Team
1—Gold Team
Returns:
teamNameName of the team (string)
teamRatingThe team’s rating at the start of the match (number)
newTeamRatingNew rating for the team when the match is complete
(number)
GetBattlefieldTimeWaited
Returns the amount of time elapsed since the player joined the queue for a
battleground/arena.
timeInQueue = GetBattlefieldTimeWaited(index)
Arguments:
indexIndex of a battleground/arena queue the player has joined (between 1
and MAX_BATTLEFIELD_QUEUES)(number)
Returns:
timeInQueueTime elapsed since the player joined the queue (in milliseconds)
(number)
GetBattlefieldVehicleInfo
Returns information about special vehicles in the current zone.
vehicleX, vehicleY, unitName, isPossessed, vehicleType, orientation, i
isPlayer, isAlive = GetBattlefieldVehicleInfo(index)
Used only for certain vehicles in certain zones: includes the airships in
Icecrown as well as vehicles used in Ulduar, Wintergrasp, and Strand of the
Ancients.
Arguments:
indexIndex of a special vehicle (between 1and GetNumBattlefield
Vehicles())(number)
Returns:
vehicleXHorizontal position of the vehicle relative to the zone map (0 =left
edge, 1=right edge) (number)
668 Part IV Reference
vehicleYVertical position of the vehicle relative to the zone map (0 =top,
1=bottom) (number)
unitNameLocalized name of the vehicle (string)
isPossessedTrue if the vehicle is controlled by another unit (boolean)
vehicleTypeToken indicating type of vehicle; some types can be used
as keys to the global VEHICLE_TEXTURES table to get display texture information
for the vehicle (string)
Airship AllianceThe Alliance flying quest hub in Icecrown
Airship HordeThe Horde flying quest hub in Icecrown
DriveA land vehicle such as a siege engine
FlyA flying vehicle
IdleA non-moving vehicle (e.g. an artillery turret)
orientationFacing angle of the vehicle ((in radians, 0 =north, values
increasing counterclockwise) (number)
isPlayerTrue if the vehicle is controlled by the player (boolean)
isAliveTrue if the vehicle has not been destroyed (boolean)
GetBattlefieldWinner
Returns the winner of the current battleground or arena match.
winner = GetBattlefieldWinner()
Returns:
winnerIndex of the winning team if in a completed match; otherwise nil
(number)
0Horde (Battleground) / Green Team (Arena)
1Alliance (Battleground) / Gold Team (Arena)
GetBattlegroundInfo
Returns information about available battlegrounds.
name, canEnter, isHoliday, minlevel = GetBattlegroundInfo(index)
Arguments:
indexIndex of a battleground (between 1and NUM_BATTLEGROUNDS)
(number)
Returns:
nameLocalized name of the battleground (Alterac Valley, Warsong Gulch, etc.)
(string)
canEnter1if the player can enter the battleground; otherwise nil (1nil)
isHoliday1if a ‘‘holiday’’ offering bonus honor is currently active for the
battleground; otherwise nil (1nil)
minlevelMinimum character level required to enter the battleground
(number)
GetBidderAuctionItems
Requests data from the server for the list of auctions bid on by the player.
Chapter 27 API Reference 669
The AUCTION_BIDDER_LIST_UPDATE event fires if new data is available;
listing information can then be retrieved using GetAuctionItemInfo() or
other Auction APIs.
GetBillingTimeRested
Returns the amount of time for which the player must be offline in order to lift
play time restrictions.
time = GetBillingTimeRested()
After playing for a number of hours, restrictions may be placed on the player’s
ability to gain loot or XP, complete quests, or use trade skills; if in such a state,
the player must log off for the period of time specified by this function in order
to return to normal play.
Only used in locales where the length of play sessions is restricted (e.g.
mainland China).
Returns:
timeOffline time required to lift play time restrictions (in minutes) (number)
GetBindLocation
Returns the name of the player’s Hearthstone location.
location = GetBindLocation()
Returns:
locationName of the player’s Hearthstone location (string)
GetBinding
Returns information about a key binding.
commandName, binding1, binding2 = GetBinding(index)
Arguments:
indexIndex in the key bindings list (between 1and GetNumBindings())
(number)
Returns:
commandNameName of the binding command (string)
binding1First key binding for the command, or nil if no key is bound
(string,binding)
binding2Second key binding for the command, or nil if no key is bound
(string,binding)
GetBindingAction
Returns the action bound to a key or key combination.
action = GetBindingAction(“key“ [, checkOverride])
Arguments:
keyA key or key combination (e.g. ‘‘CTRL-2‘‘) (string,binding)
checkOverride (optional)True to check possible override bindings for
the key,false or omitted to check only normal bindings (boolean)
670 Part IV Reference
Returns:
actionName of the action associated with the key, or the empty string (““)if
the key is not bound to an action (string)
GetBindingByKey
Returns the action bound to a key or key combination.
action = GetBindingByKey(“key“)
Arguments:
keyA key or key combination (e.g. ‘‘CTRL-2‘‘) (string,binding)
Returns:
actionName of the action associated with the key, or the empty string (““)if
the key is not bound to an action (string)
GetBindingKey
Returns the key combinations for a given binding command.
key1, ... = GetBindingKey(“COMMAND“)
Although the default UI only allows two combinations to be bound to a
command, more than two can be set via the API.
Arguments:
COMMANDName of a binding command (string)
Returns:
key1First key binding for the command, or nil if no key is bound (string,
binding)
...A list of additional bindings for the command (list)
GetBlockChance
Returns the player’s percentage chance to block with a shield.
chance = GetBlockChance()
Returns:
chancePercentage chance to block (number)
GetBonusBarOffset
Returns the current ‘‘stance’’ offset for use with the bonus action bar.
offset = GetBonusBarOffset()
This value corresponds to what ‘‘stance’’ the player is currently in, and more
specifically which set of actions correspond to that stance. Action IDs for
special stances start on action bar #7 (or NUM_ACTIONBAR_PAGES + 1), so the
offset returned by this function corresponds to the number to be added to
NUM_ACTIONBAR_PAGES in calculating action IDs for these action bars.
Note that the UI definition of ‘‘stance’’ includes not just warrior stances but
also druid shapeshift forms, rogue/druid stealth, priest shadowform, and
various other cases, but does not necessarily include all states normally
presented in the default UI’s stance/shapeshift bar (notable exclusions are
paladin auras and death knight presences).
Chapter 27 API Reference 671
Returns:
offsetOffset of the stance’s action bar in relation to NUM_ACTIONBAR_PAGES
(number)
GetBuildInfo
Returns the version information about the client.
version, internalVersion, date, uiVersion = GetBuildInfo()
Returns:
versionDisplay version number of the client (e.g. “3.1.1“)(string)
internalVersionInternal version number of the client (e.g. “9835“)
(string)
dateDate on which the client executable was built (e.g. “Apr 24
2009“); not necessarily the date it was released to the public (string)
uiVersionVersion compatibility number for UI purposes (e.g. 30100);
generally, installed addons should have this number in the Interface header
of their TOC files to avoid being marked as Out of Date and possibly not loaded
(number)
GetBuybackItemInfo
Returns information about an item recently sold to a vendor and available to
be repurchased.
name, texture, price, quantity, numAvailable, isUsable = i
GetBuybackItemInfo(index)
Arguments:
indexIndex of an item in the buyback listing (between 1and
GetNumBuybackItems())(number)
Returns:
name—Name of the item (string)
texturePathtoanicontexturefortheitem(string)
priceCurrent cost to repurchase the item from this vendor (in copper)
(number)
quantityNumber of stacked items per purchase (number)
numAvailableNumber of items available for purchase, if the vendor
has a limited stock of the item; generally 0 for buyback items (number)
isUsable1if the player can use or equip the item; otherwise nil (1nil)
GetBuybackItemLink
Returns a hyperlink for an item recently sold to a vendor and available to be
repurchased.
link = GetBuybackItemLink(index)
Arguments:
indexIndex of an item in the buyback listing (between 1and
GetNumBuybackItems())(number)
672 Part IV Reference
Returns:
linkA hyperlink for the item (string, hyperlink)
Example:
-- Print item links for every item in the buyback tab
for i=1,12 do
local link = GetBuybackItemLink(i)
if link then
print(link .. “ is available for buyback“)
end
end
GetCVar
Returns the value of a configuration variable.
string = GetCVar(“cvar“)
Causes an error if the named CVar does not exist.
Note that all values are returned as strings: use of tonumber() may be
required if using a value in a numeric context. (See also GetCVarBool() for
binary values.)
Arguments:
cvarName of a CVar (string)
Returns:
string—Value of the CVar (any)
GetCVarAbsoluteMax
Returns the absolute maximum value allowed for a configuration variable.
min = GetCVarAbsoluteMax(“cvar“)
Arguments:
cvarName of a CVar (string)
Returns:
minAbsolute maximum value allowed for the CVar (number)
GetCVarAbsoluteMin
Returns the absolute minimum value allowed for a configuration variable.
min = GetCVarAbsoluteMin(“cvar“)
Arguments:
cvarName of a CVar (string)
Returns:
minAbsolute minimum value allowed for the CVar (number)
GetCVarBool
Returns the value of a configuration variable in a format compatible with Lua
conditional expressions.
value = GetCVarBool(“cvar“)
Chapter 27 API Reference 673
All configuration variables are stored as strings; many CVars represent the
state of a binary flag and are stored as either “1“ or “0“.Thisfunction
provides a convenient way to test the state of such variables without the extra
syntax required to explicitly check for “1“ or “0“ values.
Arguments:
cvarName of a CVar (string)
Returns:
value1if the CVar’s value should be treated as true;nil if it should be
treated as false (1nil)
GetCVarDefault
Returns the default value of a configuration variable.
value = GetCVarDefault(“CVar“)
Causes an error if the named CVar does not exist.
Arguments:
CVarName of a CVar (string)
Returns:
valueDefault value of the CVar (string)
GetCVarInfo
Returns information about a configuration variable.
value, defaultValue, serverStoredAccountWide, i
serverStoredPerCharacter = GetCVarInfo(“cvar“)
Arguments:
cvarName of a CVar (string)
Returns:
valueCurrent value of the CVar (string)
defaultValueDefault value of the CVar (string)
serverStoredAccountWide1if the CVar’s value is saved on the server
and shared by all characters on the player’s account; otherwise nil (1nil)
serverStoredPerCharacter1if the CVar’s value is saved on the
server and specific to the current character; otherwise nil (1nil)
GetCVarMax
Returns the maximum recommended value for a configuration variable.
max = GetCVarMax(“cvar“)
Used in the default UI to set the upper bounds for options controlled by slider
widgets.
Arguments:
cvarName of a CVar (string)
Returns:
maxMaximum value allowed for the given CVar (number)
674 Part IV Reference
GetCVarMin
Returns the minimum recommended value for a configuration variable.
min = GetCVarMin(“cvar“)
Used in the default UI to set the lower bounds for options controlled by slider
widgets.
Arguments:
cvarName of a CVar (string)
Returns:
minMinimum value allowed for the CVar (number)
GetCategoryInfo
Returns information about an achievement/statistic category.
name, parentID, flags = GetCategoryInfo(id)
Arguments:
idThe numeric ID of an achievement/statistic category (number)
Returns:
name—Name of the category (string)
parentIDID of the parent category of which this is a sub-category, or -1if this
is a top-level category (number)
flagsVarious additional information about the category; currently unused
(0 for all existing categories) (bitfield)
GetCategoryList
Returns a list of all achievement categories.
categories = GetCategoryList()
Returns:
categoriesA list of achievement category IDs (table)
GetCategoryNumAchievements
Returns the number of achievements/statistics to display in a category.
numItems, numCompleted = GetCategoryNumAchievements(id)
Note this function does not return the total number of achievements in a
category; it only returns the number to be displayed in the default UI.
Achievements may belong to a category but not be counted for display:
e.g. among those which are part of a series (100 Quests Completed, 500 Quests
Completed), only the achievement most recently completed and the
achievement following it in the series are shown.
Arguments:
idThe numeric ID of an achievement/statistic category (number)
Returns:
numItemsNumber of achievements or statistics to display in the category
(number)
numCompletedNumber of completed achievements in the category (or 0 for
statistics) (number)
Chapter 27 API Reference 675
GetChannelDisplayInfo
Returns information about an entry in the channel list display.
name, header, collapsed, channelNumber, count, active, category, i
voiceEnabled, voiceActive = GetChannelDisplayInfo(index)
Arguments:
indexIndex of an entry in the channel list display (between 1and
GetNumDisplayChannels())(number)
Returns:
nameName of the channel or header (string)
header1if the entry is a group header; otherwise nil (1nil)
collapsed1if the entry is a collapsed group header; otherwise nil (1nil)
channelNumberNumber identifying the channel (as returned by
GetChannelList() and used by SendChatMessage() and other channel func-
tions) (number)
countNumber of characters in the channel (number)
active1if the channel is currently active; otherwise nil.(Usedforspecial
server channels, e.g. ‘‘Trade’’ and ‘‘LookingForGroup‘‘, which can only be used
under certain conditions) (1nil)
categoryCategory to which the chat channel belongs (string)
CHANNEL_CATEGORY_CUSTOMCustom channels created by players
CHANNEL_CATEGORY_GROUPGroup channels (party, raid, battleground)
CHANNEL_CATEGORY_WORLDWorld channels (General, Trade, etc.)
voiceEnabled1if voice chat is enabled for the channel; otherwise nil
(1nil)
voiceActive1if voice chat is active for the channel; otherwise nil (1nil)
GetChannelList
Returns the list of the channels the player has joined.
index, channel, ... = GetChannelList()
Returns:
indexIndex of the channel (number)
channelName of the channel (string)
...Additional index, channel pairs for each channel the player has joined
(list)
GetChannelName
Returns information about a chat channel.
channel, channelName, instanceID = GetChannelName(channelIndex) or i
GetChannelName(“channelName“)
Arguments:
channelIndexA channel ID (number)
channelNameA channel name (string)
676 Part IV Reference
Returns:
channelID of the channel (number)
channelNameName of the channel (string)
instanceIDThe channel’s instance ID, or 0 if there are not separate instances
of the channel. (number)
GetChannelRosterInfo
Returns information about a character in a chat channel in the channel list
display.
name, owner, moderator, muted, active, enabled = i
GetChannelRosterInfo(index, rosterIndex)
Arguments:
indexIndex of a channel in the channel list display (between 1and
GetNumDisplayChannels())(number)
rosterIndexIndex of a participant in the channel (between 1and count,
where count = select(5,GetChannelDisplayInfo(index))(number)
Returns:
nameName of the character (string)
owner1if the character is the channel owner; otherwise nil (1nil)
moderator1if the character is a channel moderator; otherwise nil (1nil)
muted1if the character is muted; otherwise nil (1nil)
active1if the character is currently speaking in the channel; otherwise nil
(1nil)
enabled1if the character has voice chat active for the channel; otherwise nil
(1nil)
Example:
-- Counts the number of players in the given channel who do not have
-- voice chat enabled, and prints it to chat.
-- This script should be run with the “Chat“ window open and
-- a channel selected
local index = GetSelectedDisplayChannel()
local count = select(5, GetChannelDisplayInfo(index))
local activeCount = 0
for i=1,count do
local active = select(6, GetChannelRosterInfo(index, i))
if active then
activeCount = activeCount + 1
end
end
print(activeCount .. “ of “ .. count .. “ users have voice chat i
enabled in this channel.“)
GetChatTypeIndex
Returns the numeric index corresponding to a chat message type.
index = GetChatTypeIndex(“messageGroup“)
Chapter 27 API Reference 677
These indices are used in the default UI to identify lines printed in a chat
window, allowing (for example) their color to be changed to match changes in
the player’s color preferences.
Arguments:
messageGroupToken identifying a message type (string, chatMsgType)
Returns:
indexNumeric index of the chat type (number)
GetChatWindowChannels
Returns the saved list of channels to which a chat window is subscribed.
channelName, channelId, ... = GetChatWindowChannels(index)
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
Returns:
channelNameName of the channel (string)
channelIdNumeric id for the channel (number)
...Additional channelName, channelId pairs for each channel belonging
to the chat window (list)
GetChatWindowInfo
Returns the saved settings for a chat window.
name, fontSize, r, g, b, alpha, shown, locked, docked, i
uninteractable = GetChatWindowInfo(index)
These values reflect the settings saved between sessions, which are used by the
default UI to set up the chat frames it displays.
Arguments:
indexIndex of the window you wish you get information on (starts at 1)
(number)
Returns:
nameName of the chat window (string)
fontSizeFont size for text displayed in the chat window (number)
rRed component of the window’s background color (0.0 1.0) (number)
gGreen component of the window’s background color (0.0 1.0) (number)
bBlue component of the window’s background color (0.0 1.0) (number)
alphaAlpha value (opacity) of the window’s background (0 =fully transpar-
ent, 1=fully opaque) (number)
shown1if the window should be shown; 0 if it should be hidden (number)
locked1ifthewindowshouldbelocked;0ifitshouldbemovable/resizable
(number)
docked1if the window should be docked to the main chat window; other-
wise 0 (number)
uninteractable1if the window should ignore all mouse events; otherwise 0
(number)
678 Part IV Reference
GetChatWindowMessages
Returns the saved list of messages to which a chat window is subscribed.
... = GetChatWindowMessages(index)
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
Returns:
...A list of chatMsgTypes for which the chat window is subscribed (list)
GetClickFrame
Returns the Frame object associated with the given name.
frame = GetClickFrame(“name“)
Returns nil if there is no UI object with the name given, or if the named UI
object is not a Frame.
Arguments:
nameName of a Frame or other UI object (string)
Returns:
frameA reference to the named frame (table)
GetCoinIcon
Returns an icon representing an amount of money.
icon = GetCoinIcon(amount)
Arguments:
amountAmount of money in copper (number)
Returns:
iconPath to an icon texture representing the amount (string)
Interface\Icons\INV_Misc_Coin_01Small amount of Gold
Interface\Icons\INV_Misc_Coin_02Large amount of Gold
Interface\Icons\INV_Misc_Coin_03Small amount of Silver
Interface\Icons\INV_Misc_Coin_04Large amount of Silver
Interface\Icons\INV_Misc_Coin_05Small amount of Copper
Interface\Icons\INV_Misc_Coin_06Large amount of Copper
GetCoinText
Returns a localized string describing an amount of money.
coinText = GetCoinText(amount, “separator“)
Arguments:
amountAmount of money in copper (number)
separatorString to use as separator (’, ‘ is used if nil)(string)
Returns:
coinTextText description of the amount using localized names for ‘Gold’,
‘Silver’ and ‘Copper’ (string)
Chapter 27 API Reference 679
Example:
GetCoinTextureString(10000)
-- returns “1 Gold“
GetCoinTextureString(500050)
-- returns “50 Gold, 50 Copper“
GetCoinTextureString(123456, “ / “)
-- returns “12 Gold / 4 Silver / 56 Copper“
GetCoinTextureString
Returns a string with embedded coin icons describing an amount of money.
coinText = GetCoinTextureString(amount [, fontSize])
As in most places where money amounts are shown in the UI, lesser
denominations are only shown when non-zero.
Arguments:
amountAmount of money in copper (number)
fontSize (optional)Size of the money icons. Defaults to 14. (number)
Returns:
coinTextText description of the amount using embedded tex-
ture codes for gold, silver, and copper coin icons (string)
Example:
GetCoinTextureString(10000)
-- returns “1|TInterface\\MoneyFrame\\UI_GoldIcon:14:14:2:0|t“
GetCoinTextureString(500050)
-- returns “50|TInterface\\MoneyFrame\\UI_GoldIcon:14:14:2:0|t i
50|TInterface\\MoneyFrame\\UI_CopperIcon:14:14:2:0|t“
GetCoinTextureString(123456)
-- returns “12|TInterface\\MoneyFrame\\UI_GoldIcon:14:14:2:0|t i
34|TInterface\\MoneyFrame\\UI_SilverIcon:14:14:2:0|t i
56|TInterface\\MoneyFrame\\UI_CopperIcon:14:14:2:0|t“
GetCombatRating
Returns the value of a combat rating for the player.
rating = GetCombatRating(ratingIndex)
Arguments:
ratingIndexIndex of a rating; the following global constants are provided
for convenience (number)
CR_BLOCKBlock skill
CR_CRIT_MELEEMelee critical strike chance
CR_CRIT_RANGEDRanged critical strike chance
CR_CRIT_SPELLSpell critical strike chance
680 Part IV Reference
CR_CRIT_TAKEN_MELEEMelee Resilience
CR_CRIT_TAKEN_RANGEDRanged Resilience
CR_CRIT_TAKEN_SPELLSpell Resilience
CR_DEFENSE_SKILLDefense skill
CR_DODGEDodge skill
CR_HASTE_MELEEMelee haste
CR_HASTE_RANGEDRanged haste
CR_HASTE_SPELLSpell haste
CR_HIT_MELEEMelee chance to hit
CR_HIT_RANGEDRanged chance to hit
CR_HIT_SPELLSpell chance to hit
CR_HIT_TAKEN_MELEE—Unused
CR_HIT_TAKEN_RANGED—Unused
CR_HIT_TAKEN_SPELL—Unused
CR_PARRYParry skill
CR_WEAPON_SKILLWeapon skill
CR_WEAPON_SKILL_MAINHANDMain-hand weapon skill
CR_WEAPON_SKILL_OFFHANDOffhand weapon skill
CR_WEAPON_SKILL_RANGEDRanged weapon skill
Returns:
ratingValue of the rating for the player (number)
GetCombatRatingBonus
Returns the percentage effect for the player’s current value of a given combat
rating.
ratingBonus = GetCombatRatingBonus(ratingIndex)
Used in the default UI to show tooltips with actual percentage effects (such as
increased parry chance or reduced critical strike damage taken) when mousing
over rating information in the Character window.
Arguments:
ratingIndexIndex of a rating; the following global constants are provided
for convenience (number)
CR_BLOCKBlock skill
CR_CRIT_MELEEMelee critical strike chance
CR_CRIT_RANGEDRanged critical strike chance
CR_CRIT_SPELLSpell critical strike chance
CR_CRIT_TAKEN_MELEEMelee Resilience
CR_CRIT_TAKEN_RANGEDRanged Resilience
CR_CRIT_TAKEN_SPELLSpell Resilience
CR_DEFENSE_SKILLDefense skill
CR_DODGEDodge skill
Chapter 27 API Reference 681
CR_HASTE_MELEEMelee haste
CR_HASTE_RANGEDRanged haste
CR_HASTE_SPELLSpell haste
CR_HIT_MELEEMelee chance to hit
CR_HIT_RANGEDRanged chance to hit
CR_HIT_SPELLSpell chance to hit
CR_HIT_TAKEN_MELEE—Unused
CR_HIT_TAKEN_RANGED—Unused
CR_HIT_TAKEN_SPELL—Unused
CR_PARRYParry skill
CR_WEAPON_SKILLWeapon skill
CR_WEAPON_SKILL_MAINHANDMain-hand weapon skill
CR_WEAPON_SKILL_OFFHANDOffhand weapon skill
CR_WEAPON_SKILL_RANGEDRanged weapon skill
Returns:
ratingBonusPercentage change in the underlying statistic or mechanic con-
ferred by the player’s rating value (number)
GetComboPoints
Returns the player’s number of combo points on the current target.
comboPoints = GetComboPoints()
Only applicable to Rogues and Druids in Cat Form; always returns 0 for other
classes/forms.
Returns:
comboPointsNumber of combo points (between 0 and MAX_COMBO_POINTS)
(number)
GetCompanionCooldown
Returns cooldown information for a non-combat pet or mount.
start, duration, enable = GetCompanionCooldown(“type“, index)
Arguments:
typeType of companion (string)
CRITTERA non-combat pet
MOUNT—A mount
indexIndex of a companion (between 1and GetNumCompanions(type))
(number)
Returns:
start—The value of GetTime() at the moment the cooldown began, or 0 if the
companion is ready (number)
durationThe length of the cooldown, or 0 if the companion is ready (number)
682 Part IV Reference
enable1if a Cooldown UI element should be used to display the cooldown,
otherwise 0. (Does not always correlate with whether the companion is ready.)
(number)
GetCompanionInfo
Returns information about a non-combat pet or mount.
creatureID, creatureName, spellID, icon, active = i
GetCompanionInfo(“type“, index)
Arguments:
typeType of companion (string)
CRITTERA non-combat pet
MOUNT—A mount
indexIndex of a companion (between 1and GetNumCompanions(type))
(number)
Returns:
creatureIDUnique ID of the companion (usable with PlayerModel:
SetCreature)(number)
creatureNameLocalized name of the companion (string)
spellIDThe ‘‘spell’’ for summoning the companion (usable with GetSpell
Link et al) (number)
iconPathtoanicontextureforthecompanion(string)
active1if the companion queried is currently summoned; otherwise nil
(1nil)
GetComparisonAchievementPoints
Returns the comparison unit’s total achievement points earned.
points = GetComparisonAchievementPoints()
Only accurate once the INSPECT_ACHIEVEMENT_READY event has fired
following a call to SetAchievementComparisonUnit(). No longer accurate
once ClearAchievementComparisonUnit() is called.
Returns:
pointsTotal number of achievement points earned by the comparison unit
(number)
GetComparisonCategoryNumAchievements
Returns the number of achievements completed by the comparison unit within
acategory.
numCompleted = GetComparisonCategoryNumAchievements(id)
Only accurate once the INSPECT_ACHIEVEMENT_READY event has fired
following a call to SetAchievementComparisonUnit(). No longer accurate
once ClearAchievementComparisonUnit() is called.
Arguments:
idThe numeric ID of an achievement category (number)
Chapter 27 API Reference 683
Returns:
numCompletedNumber of achievements completed by the comparison unit in
the category (number)
GetComparisonStatistic
Returns the comparison unit’s data for a statistic.
info = GetComparisonStatistic(id)
Only accurate once the INSPECT_ACHIEVEMENT_READY event has fired
following a call to SetAchievementComparisonUnit(). No longer accurate
once ClearAchievementComparisonUnit() is called.
Arguments:
idThe numeric ID of a statistic (number)
Returns:
infoThe comparison unit’s data for the statistic, or ‘‘--’’ if none has yet been
recorded for it (string)
GetContainerFreeSlots
Returns a list of open slots in a container.
slotTable = GetContainerFreeSlots(container [, returnTable])
The optional argument returnTable allows for performance optimization in
cases where this function is expected to be called repeatedly. Rather than
creating new tables each time the function is called (eventually requiring
garbage collection), an existing table can be recycled. (Note, however, that this
function does not clear the table’s contents; use wipe() first to guarantee
consistent results.)
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
returnTable (optional)Reference to a table to be filled with return values
(table)
Returns:
slotTableA table listing the indices of open slots in the given container
(table)
Example:
-- assuming the first two rows of slots in your backpack are full...
local bagSpaces = GetContainerFreeSlots(0)
print(unpack(bagSpaces))
-- Chat window shows “9 10 11 12 13 14 15 16“
-- assuming all slots but the first in the bag immediately left
-- of your backpack are full...
GetContainerFreeSlots(1, bagSpaces)
print(unpack(bagSpaces))
-- Chat window shows “1 10 11 12 13 14 15 16“
684 Part IV Reference
-- oops, it overwrote the table from before... let’s try again
wipe(bagSpaces)
GetContainerFreeSlots(1, bagSpaces)
print(unpack(bagSpaces))
-- Chat window shows “1“
GetContainerItemCooldown
Returns cooldown information about an item in the player’s bags.
start, duration, enable = GetContainerItemCooldown(container, slot)
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
slotIndex of an item slot within the container (number, containerSlotID)
Returns:
start—The value of GetTime() at the moment the cooldown began, or 0 if the
item is ready (number)
durationThe length of the cooldown, or 0 if the item is ready (number)
enable1if a Cooldown UI element should be used to display the cooldown,
otherwise 0. (Does not always correlate with whether the item is ready.)
(number)
GetContainerItemDurability
Returns durability status for an item in the player’s bags.
durability, max = GetContainerItemDurability(container, slot)
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
slotIndex of an item slot within the container (number, containerSlotID)
Returns:
durabilityThe item’s current durability (number)
maxThe item’s maximum durability (number)
GetContainerItemGems
Returns the gems socketed in an item in the player’s bags.
gem1, gem2, gem3 = GetContainerItemGems(container, slot)
The IDs returned refer to the gems themselves (not the enchantments they
provide), and thus can be passed to GetItemInfo() to get a gem’s name,
quality, icon, etc.
Arguments:
containerThe index of the container (bagID)
slotThe slot within the given container; slots are numbered left-to-right,
top-to-bottom, starting with the leftmost slot on the top row (number)
Returns:
gem1Item ID of the first gem socketed in the item (itemID)
Chapter 27 API Reference 685
gem2Item ID of the second gem socketed in the item (itemID)
gem3Item ID of the third gem socketed in the item (itemID)
GetContainerItemID
Returns the item ID of an item in the player’s bags.
id = GetContainerItemID(container, slot)
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
slotIndex of an item slot within the container (number, containerSlotID)
Returns:
idNumeric ID of the item in the given slot (itemID)
GetContainerItemInfo
Returns information about an item in the player’s bags.
texture, count, locked, quality, readable, lootable, link = i
GetContainerItemInfo(container, slot)
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
slotIndex of an item slot within the container (number, containerSlotID)
Returns:
texturePath to the icon texture for the item (string)
countNumber of items in the slot (number)
locked1if the item is locked; otherwise nil. Items become locked while
being moved, split, or placed into other UI elements (such as the mail, trade, and
auction windows). (1nil)
qualityQuality (or rarity) of the item (number, itemQuality)
readable1if the item is readable; otherwise nil.Thisvalueis
used by the default UI to show a special cursor over items such as
books and scrolls which can be read by right-clicking. (1nil)
lootable1if the item is a temporary container containing items that
can be looted; otherwise nil. Examples include the Bag of Fishing Trea-
sures and Small Spice Bag rewarded by daily quests, lockboxes (once
unlocked), and the trunks occasionally found while fishing. (1nil)
linkA hyperlink for the item (itemLink)
GetContainerItemLink
Returns a hyperlink for an item in the player’s bags.
link = GetContainerItemLink(container, slot)
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
slotIndex of an item slot within the container (number, containerSlotID)
686 Part IV Reference
Returns:
linkA hyperlink for the item (string, hyperlink)
GetContainerItemPurchaseInfo
Returns information about alternate currencies refunded for returning an item
to vendors.
money, honorPoints, arenaPoints, itemCount, refundSec = i
GetContainerItemPurchaseInfo(container, slot)
Items bought with alternate currency (honor points, arena points, or special
items such as Emblems of Heroism and Dalaran Cooking Awards) can be
returned to a vendor for a full refund, but only within a limited time after the
original purchase.
If the given container slot is empty, contains an item which cannot be returned
for an alternate currency refund, or contains an item for which the refund grace
period has expired, all returns are nil.
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
slotIndex of an item slot within the container (number, containerSlotID)
Returns:
moneyAmount of copper to be refunded (number)
honorPointsAmount of honor points to be refunded (number)
arenaPointsAmount of arena points to be refunded (number)
itemCountNumber of different item currencies to be refunded (e.g. the price
a PvP mount is in 3 currencies, as it requires multiple battlegrounds’ Marks of
Honor) (number)
refundSecSeconds remaining until this item is no longer eligible to be
returned for a refund (number)
GetContainerItemPurchaseItem
Returns information about a specific currency refunded for returning an item
to vendors.
texture, quantity, link = GetContainerItemPurchaseItem(container, i
slot, index)
See GetContainerItemPurchaseInfo for more information about alternate
currency refunds.
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
slotIndex of an item slot within the container (number, containerSlotID)
indexIndex of the currency type; between 1and itemCount,where
itemCount is the 4th return from GetContainerItemPurchaseInfo() for the
same container and slot (number)
Chapter 27 API Reference 687
Returns:
texturePath to an icon texture for the currency item (string)
quantityQuantity of the currency item to be refunded (number)
linkHyperlinkforthecurrencyitem(itemLink)
GetContainerNumFreeSlots
Returns the number of free slots in a container and the types of items it
can hold.
freeSlots, bagType = GetContainerNumFreeSlots(container)
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
Returns:
freeSlotsNumber of empty slots in the bag (number)
bagTypeBitwise OR of the item families that can be put into the
container; see GetItemFamily for details (number, bitfield)
GetContainerNumSlots
Returns the number of slots in one of the player’s bags.
numSlots = GetContainerNumSlots(container)
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
Returns:
numSlotsNumber of item slots in the container (number)
GetCorpseMapPosition
Returns the position of the player’s corpse on the world map.
corpseX, corpseY = GetCorpseMapPosition()
Returns 0,0 if the location of the player’s corpse is not visible on the current
world map.
Returns:
corpseXHorizontal position of the player’s corpse relative to the zone map
(0 =left edge, 1=right edge) (number)
corpseYVertical position of the player’s corpse relative to the zone map (0 =
top, 1=bottom) (number)
GetCorpseRecoveryDelay
Returns the amount of time left until the player can recover their corpse.
timeLeft = GetCorpseRecoveryDelay()
Applies to resurrection spells offered by other units, resurrecting by returning
to the player’s corpse as a ghost, and to resurrecting at a graveyard’s spirit
healer, if the player has recently died several times in short succession.
688 Part IV Reference
Returns:
timeLeftAmount of time remaining before the player can resurrect
(in seconds); 0 if the player can resurrect immediately (number)
GetCritChance
Returns the player’s melee critical strike chance.
critChance = GetCritChance()
Returns:
critChanceThe player’s percentage critical strike chance for melee attacks
(number)
GetCritChanceFromAgility
Returns additional critical strike chance provided by Agility.
critChance = GetCritChanceFromAgility([“unit“])
Arguments:
unit (optional)A unit to query; only valid for player and pet,defaultsto
player if omitted (string,unitID)
Returns:
critChanceAdditional percentage chance of critical strikes conferred by the
unit’s Agility statistic (number)
GetCurrencyListInfo
Returns information about a currency type (or headers in the Currency UI).
name, isHeader, isExpanded, isUnused, isWatched, count, i
extraCurrencyType, icon, itemID = GetCurrencyListInfo(index)
Arguments:
indexIndex of a currency type in the currency list (between 1and
GetCurrencyListSize())(number)
Returns:
nameName of the currency type or category header (string)
isHeaderTrue if this listing is a category header, false for actual currencies
(boolean)
isExpandedTrue if this listing is a category header whose contents are
shown, false for collapsed headers and actual currencies (boolean)
isUnusedTrue if the player has marked this currency as Unused (boolean)
isWatchedTrue if the player has marked this currency to be watched on the
backpack UI (boolean)
countAmount of the currency the player has (number)
extraCurrencyType1for Arena points, 2 for Honor points, 0 for other cur-
rencies (number)
iconPath to a texture representing the currency item (not applicable for
Arena/Honor points) (string)
itemIDID for the currency item (number)
Chapter 27 API Reference 689
GetCurrencyListSize
Returns the number of list entries to show in the Currency UI.
numEntries = GetCurrencyListSize()
Returns:
numEntriesNumber of currency types (including category headers) to be
shown in the Currency UI (number)
GetCurrentArenaSeason
Returns a number identifying the current arena season.
season = GetCurrentArenaSeason()
New arena seasons begin every few months, resetting team rankings and
providing new rewards.
Returns:
seasonNumber identifying the current arena season (number)
GetCurrentBindingSet
Returns which set of key bindings is currently in use.
bindingSet = GetCurrentBindingSet()
Returns:
bindingSetSet of bindings currently in use (number)
1Key bindings shared by all characters
2Character specific key bindings
GetCurrentGuildBankTab
Returns the currently selected guild bank tab.
GetCurrentGuildBankTab(currentTab)
Arguments:
currentTabIndex of the selected guild bank tab (between 1and
GetNumGuildBankTabs())(number)
GetCurrentKeyBoardFocus
Returns the frame currently handling keyboard input.
frame = GetCurrentKeyBoardFocus()
Typically an EditBox
Returns:
frameFrame currently handling keyboard input, or nil if no frame is cur-
rently focused (table)
Example:
# put this in a macro and try running it (from an action bar or
# somesuch) while typing in different text boxes
/run frame = GetCurrentKeyBoardFocus ()i
print(frame and frame:GetName() or “no focus“)
690 Part IV Reference
GetCurrentMapAreaID
Returns an ID number for the current map zone.
areaID = GetCurrentMapAreaID()
Currently only used in the default UI to determine whether the Wintergrasp
map is showing (and if so, display the time remaining until the next battle).
Returns:
areaIDA number identifying the current map zone (number)
GetCurrentMapContinent
Returns the current world map continent.
continent = GetCurrentMapContinent()
Returns:
continentIndex of the world map’s current continent (in the list returned
by GetMapContinents(), or one of the following values) (number)
-1—Cosmic map
0—Full Azeroth map
1Kalimdor
2Eastern Kingdoms
3—Outlands
4—Northrend
GetCurrentMapDungeonLevel
Returns which map image is currently selected on the world map (for zones
which use more than one map image).
level = GetCurrentMapDungeonLevel()
Used in zones with more than one ‘‘floor’’ or area, such as Dalaran and several
Wrath of the Lich King dungeons and raids. More than one map image may
contain the player’s current location; if the world map has not been explicitly
set to show a particular area, this returns whichever is the ‘‘best’’ match.
Returns:
levelIndex of the current map image (number)
GetCurrentMapZone
Returns the current world map zone.
zone = GetCurrentMapZone()
Returns:
zoneIndex of a zone within the continent (in the list returned by
GetMapZones(GetCurrentMapContinent())), or 0 for the continent map
(number)
GetCurrentMultisampleFormat
Returns the index of the current multisample setting.
index = GetCurrentMultisampleFormat()
The index returned corresponds to the individual settings described by
GetMultisampleFormats() (each a set of three values).
Chapter 27 API Reference 691
Returns:
indexIndex of the current multisample setting (number)
GetCurrentResolution
Returns the index of the current resolution setting.
index = GetCurrentResolution()
For the dimensions of a resolution setting, use GetScreenResolutions().
Returns:
indexIndex of the current resolution setting (number)
Example:
-- Print the current resolution to chat
local index = GetCurrentResolution();
local resolution = select(index, GetScreenResolutions());
print(“Current resolution:“, resolution);
GetCurrentTitle
Returns the currently selected player title.
currentTitle = GetCurrentTitle()
Returns:
currentTitleIndex of the player’s current title (between 1and
GetNumTitles())(integer)
GetCursorInfo
Returns information about the contents of the cursor.
type, data, subType = GetCursorInfo()
Returns:
typeType of data attached to the cursor (string)
companion
equipmentset
guildbankmoney
item
macro
merchant
money
spell
dataIdentifier for the data on the cursor; varies by type: (value)
companionIndex of the companion in the non-combat pet or mount list
(number)
equipmentsetName of the equipment set (string)
guildbankmoneyAmount of the money from the guild bank (in copper)
(number)
itemNumeric identifier for the item (number,itemID)
macroIndex of the macro in the macro listing (number,macroID)
merchantIndex of the item in the vendor’s listings (number)
moneyAmount of the player’s money (in copper) (number)
spellIndex of the spell in the player’s spellbook (number,spellbookID)
692 Part IV Reference
subTypeSecondary identifier for the data on the cursor; used only for certain
types: (string)
companion“CRITTER“ or “MOUNT“, indicating whether the
returned data is an index in the non-combat pet or mount list
item—A complete hyperlink for the item
spell“spell“ or “pet“, indicating whether the returned data is an index
in the player’s or pet’s spellbook
GetCursorMoney
Returns the amount of money currently on the cursor.
cursorMoney = GetCursorMoney()
Returns:
cursorMoneyAmount of money currently on the cursor (in copper) (number)
GetCursorPosition
Returns the absolute position of the mouse cursor.
cursorX, cursorY = GetCursorPosition()
Returns:
cursorXScale-independent X coordinate of the cursor’s current position
(number)
cursorYScale-independent Y coordinate of the cursor’s current position
(number)
GetDailyQuestsCompleted
Returns the number of daily quests the player has completed today.
dailyQuestsComplete = GetDailyQuestsCompleted()
The daily quest period resets at or around 3:00 AM server time on most realms.
Returns:
dailyQuestsCompleteNumber of daily quests completed in the current
period (number)
GetDamageBonusStat
Returns the index of the basic statistic that provides increased physical
damage.
bonusStat = GetDamageBonusStat()
Unused in the default UI.
Returns:
bonusStatIndex of the basic statistic which provides attack (number)
1Strength (Druids, Mages, Paladins, Priests, Shamans, Warlocks and
Warriors)
2Agility (Hunters and Rogues)
GetDeathReleasePosition
Returns the location of the graveyard where the player’s spirit will appear
upon release.
graveyardX, graveyardY = GetDeathReleasePosition()
Chapter 27 API Reference 693
Returns 0,0 if the player is not dead or the graveyard’s location is not visible
on the current world map.
Returns:
graveyardXHorizontal position of the graveyard relative to the zone map
(0 =left edge, 1=right edge) (number)
graveyardYVertical position of the graveyard relative to the zone map (0 =
top, 1=bottom) (number)
GetDefaultLanguage
Returns the name of the player character’s default language.
language = GetDefaultLanguage()
This is the language used in the chat system (Common or Orcish, as opposed to
Taurahe, Darnassian, etc), not the real-world language of the client or server.
Returns:
languageLocalized name of the player character’s default language (string)
GetDodgeChance
Returns the player’s chance to dodge melee attacks.
chance = GetDodgeChance()
Returns:
chancePercentage chance to dodge melee attacks (number)
GetDungeonDifficulty
Returns the 5 player selected dungeon difficulty.
difficulty = GetDungeonDifficulty()
Returns:
difficultyThe current 5 player dungeon difficulty (number)
1—Normal
2—Heroic
GetEquipmentSetInfo
Returns information about an equipment set (specified by index).
name, icon, setID = GetEquipmentSetInfo(index)
Arguments:
indexIndex of an equipment set (between 1and GetNumEquipmentSets())
(number)
Returns:
nameName of the equipment set (string)
iconPath to an icon texture for the equipment set (string)
setIDInternal ID number for the set (not used elsewhere in API) (number)
GetEquipmentSetInfoByName
Returns information about an equipment set.
icon, setID = GetEquipmentSetInfoByName(“name“)
694 Part IV Reference
Arguments:
nameName of an equipment set (case sensitive) (string)
Returns:
iconUnique part of the path to an icon texture for the equipment
set; prepend “Interface\Icons\“ for the full path (string)
setIDInternal ID number for the set (not used elsewhere in API) (number)
GetEquipmentSetItemIDs
Returns a table listing the items in an equipment set.
itemIDs = GetEquipmentSetItemIDs(“name“)
Arguments:
nameName of an equipment set (case sensitive) (string)
Returns:
itemIDsA table listing the itemIDs of the set’s contents, keyed by
inventoryID (table)
GetEquipmentSetLocations
Returns a table listing the locations of the items in an equipment set.
itemIDs = GetEquipmentSetLocations(“name“)
Arguments:
nameName of an equipment set (case sensitive) (string)
Returns:
itemIDsA table listing the itemLocations of the set’s contents, keyed by
inventoryID (table)
GetEventCPUUsage
Returns information about the CPU usage of an event.
usage, numEvents = GetEventCPUUsage([“event“])
Only returns valid data if the scriptProfile CVar is set to 1; returns 0
otherwise.
Arguments:
event (optional)Name of an event; if omitted, returns usage information for
all events (string)
Returns:
usageAmount of CPU time used by handlers for the event (in milliseconds)
since the UI was loaded or ResetCPUUsage() was last called (number)
numEventsNumber of times the event has fired this session (number)
GetExistingLocales
Returns a list of installed localization packs for the WoW client.
... = GetExistingLocales()
Returns:
...A list of strings, each the four-letter locale code (see GetLocale())foran
installed localization (list)
Chapter 27 API Reference 695
GetExistingSocketInfo
Returns information about a permanently socketed gem.
name, texture, name = GetExistingSocketInfo(index)
If the given socket contains a permanently socketed gem, returns information
for that gem (even if a new gem has been dropped in the socket to overwrite
the existing gem, but has not yet been confirmed). If the socket is empty,
returns nil.
Only returns valid information when the Item Socketing UI is open
(i.e. between the SOCKET_INFO_UPDATE and SOCKET_INFO_CLOSE events).
Arguments:
indexIndex of a gem socket (between 1and GetNumSockets())(number)
Returns:
nameName of the socketed gem (string)
texturePath to an icon texture for the socketed gem (string)
name1if the gem matches the socket’s color; otherwise nil (1nil)
GetExistingSocketLink
Returns a hyperlink for a permanently socketed gem.
link = GetExistingSocketLink(index)
If the given socket contains a permanently socketed gem, returns an item link
for that gem (even if a new gem has been dropped in the socket to overwrite
the existing gem, but has not yet been confirmed). If the socket is empty,
returns nil.
Only returns valid information when the Item Socketing UI is open
(i.e. between the SOCKET_INFO_UPDATE and SOCKET_INFO_CLOSE events).
Arguments:
indexIndex of a gem socket (between 1and GetNumSockets())(number)
Returns:
linkA hyperlink for the socketed gem (string, hyperlink)
GetExpertise
Returns the player’s current expertise value.
expertise = GetExpertise()
Returns:
expertiseThe player’s expertise value (number)
GetExpertisePercent
Returns the reduction in chance to be dodged or parried conferred by the
player’s expertise value.
expertisePerc, offhandExpertisePercent = GetExpertisePercent()
Returns:
expertisePercReduction in percentage chance for main hand attacks to be
dodged or parried (number)
696 Part IV Reference
offhandExpertisePercentReduction in percentage chance for off hand
attacks to be dodged or parried (number)
GetFacialHairCustomization
Returns a token used for displaying facial feature customization options.
token = GetFacialHairCustomization()
The token referred to by this function can be used to look up a global variable
containing localized names for the customization options available to the
player’s race at character creation time and in the Barbershop UI; see example.
Returns:
tokenPart of a localized string token for displaying facial feature options for
theplayersrace(
string)
Example:
-- prints localized names for customization options
-- e.g. “Facial Hair“, “Earrings“, “Tusks“
local token = GetFacialHairCustomization();
print(_G[“FACIAL_HAIR_“..token]);
GetFactionInfo
Returns information about a faction or header listing.
name, description, standingID, barMin, barMax, barValue, atWarWith, i
canToggleAtWar, isHeader, isCollapsed, hasRep, isWatched, i
isChild = GetFactionInfo(index)
Arguments:
indexThe index of the faction in the Reputation window (number)
Returns:
name—Name of the faction (string)
descriptionBrief description of the faction, as displayed in the
default UI’s detail window for a selected faction (string)
standingIDCurrent standing with the given faction (number,standingID)
1—Hated
2Hostile
3—Unfriendly
4—Neutral
5—Friendly
6Honored
7Revered
8—Exalted
barMinThe minimum value of the reputation bar at the given standing
(number)
barMaxThe maximum value of the reputation bar at the given standing
(number)
barValueThe player’s current reputation with the faction (number)
atWarWith1if the player is at war with the given faction, otherwise nil
(1nil)
canToggleAtWar1if the player can declare war with the given faction, other-
wise nil (1nil)
isHeader1if the index refers to a faction group header (1nil)
Chapter 27 API Reference 697
isCollapsed1if the index refers to a faction group header and currently col-
lapsed (1nil)
hasRep1if the index refers to a faction group header whose reputation value
should be displayed (1nil)
isWatched1if the faction is currently being watched (i.e. displayed above the
experience bar) (1nil)
isChild1if the index refers to a faction sub-group header within
another group, or to an individual faction within a sub-group (1nil)
GetFirstTradeSkill
Returns the index of the first non-header in the trade skill listing.
index = GetFirstTradeSkill()
Returns:
indexIndex of the first trade skill recipe (as opposed to group headers)
(number)
GetFrameCPUUsage
Returns information about CPU usage by a frame’s script handlers.
usage, calls = GetFrameCPUUsage(frame, includeChildren)
Only returns valid data if the scriptProfile CVar is set to 1; returns 0
otherwise.
Arguments:
frame—A Frame object (table)
includeChildrenTrue to include CPU usage by children of
the frame; false to include only the frame itself (boolean)
Returns:
usageAmount of CPU time used by the frame’s script handlers (in millisec-
onds) since the UI was loaded or ResetCPUUsage() was last called (number)
callsNumber of function calls made from the frame’s script handlers
(number)
GetFramerate
Returns the number of frames per second rendered by the client.
framerate = GetFramerate()
Returns:
framerateNumber of frames per second rendered by the client (number)
GetFramesRegisteredForEvent
Returns all frames registered for a given event.
... = GetFramesRegisteredForEvent(“event“)
Arguments:
eventAn event name (string)
698 Part IV Reference
Returns:
...A list of tables, each a reference to a frame registered for the event (list)
Example:
-- Print the names of any named frames registered for an event
local function printFrameNames(...)
for i=1,select(“#“, ...) do
local frame = select(i, ...)
local name = frame:GetName()
if name then
ChatFrame1:AddMessage(name)
end
end
end
printFrameNames(GetFramesRegisteredForEvent(UNIT_HEALTH“))
GetFriendInfo
Returns information about a character on the player’s friends list.
name, level, class, area, connected, status, note, RAF = i
GetFriendInfo(index)
Arguments:
indexIndex of a character in the Friends list (between 1and
GetNumFriends())(number)
Returns:
nameName of the friend (string)
levelCharacter level of the friend, if online; otherwise 0 (number)
classLocalized name of the friend’s class, if online; otherwise UNKNOWN
(string)
areaName of the zone in which the friend is located, if online; otherwise
UNKNOWN (string)
connected1if the friend is online; otherwise nil (1nil)
statusA label indicating the friend’s status (“<AFK>“ or “<DND>“), or the
emptystring(
““) if not applicable (string)
noteNote text associated with the friend (string)
RAF1if the friend’s account is linked to the player’s via the Recruit-A-Friend
program; otherwise nil (1nil)
GetFunctionCPUUsage
Returns information about CPU usage by a function.
usage, calls = GetFunctionCPUUsage(function, includeSubroutines)
Only returns valid data if the scriptProfile CVar is set to 1; returns 0
otherwise.
Arguments:
functionA function reference (function)
Chapter 27 API Reference 699
includeSubroutinesTrue to include time spent in other functions called
by the given function; false to count only time spent in the function body
(boolean)
Returns:
usageAmount of CPU time used by the function (in milliseconds) since
the UI was loaded or ResetCPUUsage() was last called (number)
callsNumber of times the function was called (number)
GetGMTicket
Requests GM ticket status from the server.
The UPDATE_TICKET event fires when data is ready.
GetGameTime
Returns the current realm (server) time.
hour, minute = GetGameTime()
Returns:
hourHour portion of the time (on a 24-hour clock) (number)
minuteMinute portion of the time (number)
GetGamma
Returns the current display gamma setting.
gamma = GetGamma()
Gamma value determines the contrast between lighter and darker portions of
the game display; for a detailed explanation, see the Wikipedia entry on
Gamma correction entry.
Returns:
gammaCurrent gamma setting (number)
GetGlyphLink
Gets a hyperlink for the contents of a glyph socket.
link = GetGlyphLink(socket, talentGroup)
Glyph links are distinct from item and spell links: e.g.
‘‘|cff66bbff|Hglyph:21:361|h[Glyph of Hunter’s Mark]|h|r‘‘.
Arguments:
socketWhich glyph socket to query (between 1and NUM_GLYPH_SLOTS)
(number,glyphIndex)
talentGroupWhich set of glyphs to query, if the player has Dual Talent Spe-
cialization enabled (number)
1Primary Talents
2—Secondary Talents
nilCurrently active talents
Returns:
linkA hyperlink for the glyph socket’s contents, or ‘‘’’ if the socket is empty
(string, hyperlink)
700 Part IV Reference
GetGlyphSocketInfo
Returns information about a glyph socket and its contents.
enabled, glyphType, glyphSpell, icon = GetGlyphSocketInfo(socket, i
talentGroup)
The spell ID referenced in the third return glyphSpell refers to the spell used to
put the glyph in the socket. Note the Inscription spell that creates a glyph item,
but the spell associated with that item’s ‘‘Use:’’ effect.
Arguments:
socketWhich glyph socket to query (between 1and NUM_GLYPH_SLOTS)
(number,glyphIndex)
talentGroupWhich set of glyphs to query, if the player has Dual Talent Spe-
cialization enabled (number)
1Primary Talents
2—Secondary Talents
nilCurrently active talents
Returns:
enabledTrue if the socket can be given a glyph at the player’s current level;
false if the socket is locked (boolean)
glyphType1for major glyph sockets, 2 for minor glyph sockets (number)
glyphSpellSpell ID of the spell that inscribed a glyph into the socket, or nil
if the socket is empty (number)
iconPath to a texture for the glyph inscribed into the socket, or nil if the
socket is empty (string)
GetGossipActiveQuests
Returns a list of quests which can be turned in to the current Gossip NPC.
name, level, isTrivial, ... = GetGossipActiveQuests()
These quests are displayed with a question mark icon in the default UI’s
GossipFrame.
Returns:
name—Name of the quest (string)
levelSuggested character level for attempting the quest (number)
isTrivial1if the quest is considered ‘‘trivial’’ at the player’s level (rewards
no XP); otherwise nil (1nil)
...Additional name, level, isTrivial values if more than one quest is
active (list)
GetGossipAvailableQuests
Returns a list of quests available from the current Gossip NPC.
name, level, isTrivial, ... = GetGossipAvailableQuests()
These quests are displayed with an exclamation mark icon in the default UI’s
GossipFrame.
Chapter 27 API Reference 701
Returns:
name—Name of the quest (string)
levelSuggested character level for attempting the quest (number)
isTrivial1if the quest is considered ‘‘trivial’’ at the player’s level (rewards
no XP); otherwise nil (1nil)
...Additional name, level, isTrivial values if more than one quest is
active (list)
GetGossipOptions
Returns a list of interaction options for the Gossip NPC.
text, gossipType, ... = GetGossipOptions()
Returns:
textText to be displayed for the gossip option (string)
gossipTypeNon-localized string indicating the type of gossip option
(string)
BankerBegin a Bank interaction
BattleMasterQueue for a battleground instance
BinderSet the player’s Hearthstone location
Gossip—Talk to the NPC
TabardBegin a Tabard design interaction
TaxiBegin a Taxi (flight master) interaction
TrainerBegin a Trainer interaction
VendorBegin a Merchant interaction
...Additional text, gossipType values for each gossip option available
(list)
GetGossipText
Returns greeting or other text to be displayed in an NPC dialog.
text = GetGossipText()
Returns:
textText to be displayed for the NPC conversation (string)
GetGreetingText
Returns the greeting text displayed for quest NPCs with multiple quests.
greetingText = GetGreetingText()
Not used often; most quest NPCs offering multiple quests (and/or other
options) use the Gossip functions to provide a greeting (see
GetGossipText()).
Returns:
greetingTextText to be displayed before choosing from among the NPC’s
multiple quests (string)
GetGroupPreviewTalentPointsSpent
Returns the total number of points spent in the Talent UI’s preview mode.
pointsSpent = GetGroupPreviewTalentPointsSpent(isPet, talentGroup)
702 Part IV Reference
This function only counts points spent in the preview mode, not those actually
learned.
Arguments:
isPettrue to query talent info for the player’s pet, false to query talent info
for the player (boolean)
talentGroupWhich set of talents to edit, if the player has Dual Talent Special-
ization enabled (number)
1Primary Talents
2—Secondary Talents
nilCurrently active talents
Returns:
pointsSpentNumber of points spent in preview mode (number)
GetGuildBankItemInfo
Returns information about the contents of a guild bank item slot.
texture, count, locked = GetGuildBankItemInfo(tab, slot)
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
slotIndex of an item slot in the guild bank tab (between 1and
MAX_GUILDBANK_SLOTS_PER_TAB)(number)
Returns:
texturePathtoanicontexturefortheitem(string)
countNumber of stacked items in the slot (number)
locked1if the slot is locked (as when a guild member has picked up
an item and not yet deposited it elsewhere); otherwise nil (1nil)
GetGuildBankItemLink
Returns a hyperlink for an item in the guild bank.
item = GetGuildBankItemLink(tab, slot)
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
slotIndex of an item slot in the guild bank tab (between 1and
MAX_GUILDBANK_SLOTS_PER_TAB)(number)
Returns:
itemA hyperlink for the contents of the slot (string, hyperlink)
GetGuildBankMoney
Returns the amount of money in the guild bank.
guildBankMoney = GetGuildBankMoney()
The return value is cached and returns the last value seen when not interacting
with a guild bank vault. This cache works across characters, and is updated
when the GUILDBANK_UPDATE_MONEY or GUILDBANKFRAME_OPENED event
Chapter 27 API Reference 703
fires. If no player character has accessed a guild bank since the game client was
launched, this function returns 0.
Returns:
guildBankMoneyAmount of money in the guild bank (in copper) (number)
GetGuildBankMoneyTransaction
Returns information about a transaction in the guild bank money log.
type, name, year, month, day, hour = GetGuildBankMoneyTransaction(index)
Arguments:
indexIndex of a transaction in the money log (between 1and
GetNumGuildBankMoneyTransactions())(number)
Returns:
typeType of log event (string)
depositDeposit into the guildbank
repairRepair cost withdrawal from the guildbank
withdrawWithdrawal from the guildbank
nameName of the guild member responsible for the event, or nil if the name
is unknown (string)
yearNumber of years since the event occurred (number)
monthNumber of months since the event occurred (number)
dayNumber of days since the event occurred (number)
hourNumber of hours since the event occurred (number)
GetGuildBankTabCost
Returns the cost of the next available guild bank tab.
tabCost = GetGuildBankTabCost()
Returns:
tabCostCost to purchase the next guild bank tab (in copper) (number)
GetGuildBankTabInfo
Returns information about a guild bank tab.
name, icon, isViewable, canDeposit, numWithdrawals, i
remainingWithdrawals = GetGuildBankTabInfo(tab)
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
Returns:
name—Name of the tab (string)
iconPath to the icon texture for the tab (string)
isViewable1if the player is allowed to view the contents of the tab; other-
wise nil (1nil)
canDeposit1if the player is allowed to deposit items into the tab; otherwise
nil (1nil)
704 Part IV Reference
numWithdrawalsMaximum number of items (stacks) the player is allowed to
withdraw from the tab per day (number)
remainingWithdrawalsMaximum number of items (stacks) the
player is currently allowed to withdraw from the tab (number)
GetGuildBankTabPermissions
Returns information about guild bank tab privileges for the guild rank
currently being edited.
canView, canDeposit, numWithdrawals = GetGuildBankTabPermissions(tab)
Used in the default UI’s guild control panel.
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
Returns:
canView1if the guild rank has permission to view the tab’s contents; other-
wise nil (1nil)
canDeposit1if the guild rank has permission to deposit items into the tab;
otherwise nil (1nil)
numWithdrawalsMaximum number of withdrawals per day the guild rank is
allowed for the given tab (number)
GetGuildBankText
Returns text associated with a guild bank tab.
text = GetGuildBankText(tab)
Only returns valid data after QueryGuildBankText() has been called to
retrieve the text from the server and the following GUILDBANK_UPDATE_TEXT
event has fired.
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
Returns:
textInfo text provided for the tab (string)
GetGuildBankTransaction
Returns information about a transaction in the log for a guild bank tab.
type, name, itemLink, count, tab1, tab2, year, month, day, hour = i
GetGuildBankTransaction(tab, index)
Only returns valid information following the GUILDBANKLOG_UPDATE event
which fires after calling QueryGuildBankLog().
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
indexIndex of a log entry (between 1and GetNumGuildBankTransactions
(tab))(number)
Chapter 27 API Reference 705
Returns:
typeType of transaction (string)
deposit
move
repair
withdraw
nameName of the guild member responsible for the transaction (string)
itemLinkA hyperlink for the item involved in the transaction (string,
hyperlink)
countNumber of stacked items involved in the transaction (number)
tab1Index of the source tab, if the item was moved between tabs (number)
tab2Index of the destination tab, if the item was moved between tabs
(number)
yearNumber of years since the event occurred (number)
monthNumber of months since the event occurred (number)
dayNumber of days since the event occurred (number)
hourNumber of hours since the event occurred (number)
GetGuildBankWithdrawLimit
Returns the guild bank money withdrawal limit for the guild rank currently
being edited.
goldWithdrawLimit = GetGuildBankWithdrawLimit()
Returns:
goldWithdrawLimitAmount of money the guild rank is allowed to
withdraw from the guild bank per day (in copper), or -1if the guild rank has
unlimited withdrawal privileges (number)
GetGuildBankWithdrawMoney
Returns the amount of money the player is allowed to withdraw from the guild
bank per day.
withdrawLimit = GetGuildBankWithdrawMoney()
Returns:
withdrawLimitAmount of money the player is allowed to withdraw from
the guild bank per day (in copper), or -1if the player has unlimited withdrawal
privileges (number)
GetGuildCharterCost
Returns the cost to purchase a guild charter.
cost = GetGuildCharterCost()
Usable if the player is interacting with a guild registrar (i.e. between the
GUILD_REGISTRAR_SHOW and GUILD_REGISTRAR_CLOSED events).
Returns:
costCost to purchase a guild charter (in copper) (number)
706 Part IV Reference
GetGuildEventInfo
Returns information about an entry in the guild event log.
type, player1, player2, rank, year, month, day, hour = i
GetGuildEventInfo(index)
Only returns valid data after calling QueryGuildEventLog() and the
following GUILD_EVENT_LOG_UPDATE event has fired.
Arguments:
indexIndex of an entry in the guild event log (between 1and
GetNumGuildEvents())(number)
Returns:
typeType of event (example descriptions from the default UI below) (string)
demote—player1demotes player2 to rank.
invite—player1invites player2 to the guild.
join—player1joins the guild.
promote—player1promotes player2 to rank.
quit—player1has quit the guild.
remove—player1removes player2 from the guild.
player1First actor in the event (string)
player2Second actor in the event, if applicable (string)
rankName of the rank related to promote/demote events (string)
yearNumber of years since the event occurred (number)
monthNumber of months since the event occurred (number)
dayNumber of days since the event occurred (number)
hourNumber of hours since the event occurred (number)
GetGuildInfo
Returns a unit’s guild affiliation.
guildName, guildRankName, guildRankIndex = GetGuildInfo(“unit“) or i
GetGuildInfo(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
guildNameName of the character’s guild (string)
guildRankNameName of the character’s guild rank (string)
guildRankIndexNumeric guild rank of the character (0 =guild leader;
higher numbers for lower ranks) (number)
GetGuildInfoText
Returns guild information text.
guildInfoText = GetGuildInfoText()
Chapter 27 API Reference 707
Only returns valid data after calling GuildRoster() and the following
GUILD_ROSTER_UPDATE event has fired.
This text appears when clicking the ‘‘Guild Information’’ button in the default
UI’s Guild window.
Returns:
guildInfoTextThe guild information text (including newline characters)
(string)
GetGuildRosterInfo
Returns information about the selected player in your guild roster.
name, rank, rankIndex, level, class, zone, note, officernote, i
online, status, classFileName = GetGuildRosterInfo(index)
Only returns valid data after calling GuildRoster() and the following
GUILD_ROSTER_UPDATE event has fired.
Arguments:
indexIndex of a member in the guild roster (between 1and
GetNumGuildMembers()), or 0 for no selection (number)
Returns:
nameName of the member (string)
rankName of the member’s rank (string)
rankIndexNumeric rank of the member (0 =guild leader; higher numbers
for lower ranks) (number)
levelCharacter level of the member (number)
classLocalized name of the member’s class (string)
zoneZone in which the member was last seen (string)
notePublic note text for the member (string)
officernoteOfficer note text for the member, or the empty string
(““) if the player is not allowed to view officer notes (string)
online1if the member is currently online; otherwise nil (1nil)
statusStatus text for the member (string)
<AFK>Is away from keyboard
<DND>Does not want to be disturbed
classFileNameNon-localized token representing the member’s class
(string)
GetGuildRosterLastOnline
Returns the amount of time since a guild member was last online.
years, months, days, hours = GetGuildRosterLastOnline(index)
Only returns valid data after calling GuildRoster() and the following
GUILD_ROSTER_UPDATE event has fired.
Arguments:
indexIndex of a member in the guild roster (between 1and
GetNumGuildMembers()), or 0 for no selection (number)
708 Part IV Reference
Returns:
yearsNumber of years since the member was last online (number)
monthsNumber of months since the member was last online (number)
daysNumber of days since the member was last online (number)
hoursNumber of hours since the member was last online (number)
GetGuildRosterMOTD
Returns the Message of the Day for the player’s guild.
guildMOTD = GetGuildRosterMOTD()
Returns:
guildMOTDThe guild Message of the Day (string)
GetGuildRosterSelection
Returns the index of the selected member in the guild roster.
index = GetGuildRosterSelection()
Selection in the guild roster is used only for display in the default UI and has
no effect on other Guild APIs.
Returns:
indexIndex of the selected member in the guild roster (between
1and GetNumGuildMembers()), or 0 for no selection (number)
GetGuildRosterShowOffline
Returns whether the guild roster lists offline members.
showOffline = GetGuildRosterShowOffline()
Returns:
showOffline1if offline members are included in the guild roster listing; oth-
erwise nil (1nil)
GetGuildTabardFileNames
Returns the textures that comprise the player’s guild tabard.
tabardBackgroundUpper, tabardBackgroundLower, tabardEmblemUpper, i
tabardEmblemLower, tabardBorderUpper, tabardBorderLower = i
GetGuildTabardFileNames()
Returns nil if the player is not in a guild.
Returns:
tabardBackgroundUpperPath to the texture for the upper portion of the
tabard’s background (string)
tabardBackgroundLowerPath to the texture for the lower portion of the
tabard’s background (string)
tabardEmblemUpperPath to the texture for the upper portion of the tabard’s
emblem (string)
tabardEmblemLowerPath to the texture for the lower portion of the tabard’s
emblem (string)
tabardBorderUpperPath to the texture for the upper portion of the tabard’s
border (string)
Chapter 27 API Reference 709
tabardBorderLowerPath to the texture for the lower portion of the tabard’s
border (string)
GetHairCustomization
Returns a token used for displaying ‘‘hair’’ customization options.
token = GetHairCustomization()
The token referred to by this function can be used to look up a global variable
containing localized names for the customization options available to the
player’s race at character creation time and in the Barbershop UI; see example.
Returns:
tokenPart of a localized string token for displaying ‘‘hair’’ options for the
player’s race (string)
Example:
-- prints localized names for customization options
-- e.g. “Hair Style“/“Hair Color“ or “Horn Style“/“Horn Color“
local token = GetHairCustomization();
print(_G[“HAIR_“..token..“_STYLE“]);
print(_G[“HAIR_“..token..“_COLOR“]);
GetHonorCurrency
Returns the player’s amount of honor points.
honorPoints, maxHonor = GetHonorCurrency()
Returns:
honorPointsThe player’s current amount of honor points (number)
maxHonorThe maximum amount of honor currency the player can accrue
(number)
GetIgnoreName
Returns the name of a character on the ignore list.
name = GetIgnoreName(“index“)
Arguments:
indexIndex of an entry in the ignore list (between 1and GetNumIgnores())
(string)
Returns:
nameName of the ignored character (string)
GetInboxHeaderInfo
Returns information about a message in the player’s inbox.
packageIcon, stationeryIcon, sender, subject, money, CODAmount, i
daysLeft, itemCount, wasRead, wasReturned, textCreated, canReply, i
isGM, itemQuantity = GetInboxHeaderInfo(mailID)
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
Returns:
packageIconPath to an icon texture for the message if it contains an item; nil
for other messages (string)
710 Part IV Reference
stationeryIconPath to an icon texture for the message (string)
senderName of the message’s sender (string)
subjectSubject text of the message (string)
moneyAmount of money attached to the message (in copper) (number)
CODAmountCash-On-Delivery cost to take any items attached to the message
(in copper) (number)
daysLeftNumber of days remaining before the message is automatically
returned or deleted (number)
itemCountNumber of item attachments to the message (number)
wasRead1if the player has read the message; otherwise nil (1nil)
wasReturned1if the message is a message that was sent by the player
to another character and returned by the recipient; otherwise nil (1nil)
textCreated1if the player has saved a copy of the message text as an item;
otherwise nil (1nil)
canReply1if the player can reply to the message; otherwise nil (1nil)
isGM1if the message is from a game master; otherwise nil (1nil)
itemQuantityNumber of stacked items attached to the message if the mes-
sage has one attachment; nil if the message has zero or multiple attachments
(number)
GetInboxInvoiceInfo
Returns auction house invoice information for a mail message.
invoiceType, itemName, playerName, bid, buyout, deposit, consignment, i
moneyDelay, etaHour, etaMin = GetInboxInvoiceInfo(index)
Arguments:
indexIndex of the mail message in the inbox (between 1and
GetInboxNumItems())(number)
Returns:
invoiceTypeType of invoice (string)
buyerAninvoiceforanitemtheplayerwon
sellerAninvoiceforanitemtheplayersold
seller_temp_invoiceA temporary invoice for an item sold by
the player but for which payment has not yet been delivered
itemName—Name of the item (string)
playerNameName of the player who bought or sold the item (string)
bidAmount of the winning bid or buyout (number)
buyoutAmount of buyout (if the auction was bought out) (number)
depositAmount of money paid in deposit (number)
consignmentAmount withheld from the deposit by the auction house as
charge for running the auction (number)
moneyDelayDelay for delivery of payment on a temporary invoice (in min-
utes; generally 60) (number)
etaHourHour portion (on a 24-hour clock) of the estimated time for delivery
of payment on a temporary invoice (number)
Chapter 27 API Reference 711
etaMinMinute portion of the estimated time for delivery of payment on a
temporary invoice (number)
GetInboxItem
Returns information for an item attached to a message in the player’s inbox.
name, itemTexture, count, quality, canUse = GetInboxItem(mailID, i
attachmentIndex)
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
attachmentIndexIndex of an attachment to the message (between
1and select(8,GetInboxHeaderInfo(mailID)))(number)
Returns:
name—Name of the item (string)
itemTexturePathtoanicontexturefortheitem(string)
countNumber of stacked items (number)
qualityQuality (rarity) of the item (number, itemQuality)
canUse1if the player can use or equip the item; otherwise nil (1nil)
GetInboxItemLink
Returns a hyperlink for an item attached to a message in the player’s inbox.
itemlink = GetInboxItemLink(mailID, attachmentIndex)
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
attachmentIndexIndex of an attachment to the message (between
1and select(8,GetInboxHeaderInfo(mailID)))(number)
Returns:
itemlinkA hyperlink for the attachment item (string, hyperlink)
GetInboxNumItems
Returns the number of messages in the player’s inbox.
numItems = GetInboxNumItems()
Returns:
numItemsNumber of messages in the player’s inbox (number)
GetInboxText
Returns information about the text of an inbox message.
bodyText, texture, isTakeable, isInvoice = GetInboxText(mailID)
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
Returns:
bodyTextText of the message (string)
712 Part IV Reference
textureUnique part of the path to a background texture to be dis-
played for the message; actual texture paths are STATIONERY_PATH ..
texture .. “1“ and STATIONERY_PATH .. texture .. “2“ (string)
isTakeable1if the text of the message can be saved as an item; otherwise
nil (1nil)
isInvoice1if the inbox message is an auction house invoice; otherwise nil
(1nil)
GetInspectArenaTeamData
Returns arena team information about the currently inspected unit.
teamName, teamSize, teamRating, teamPlayed, teamWins, playerPlayed, i
playerRating, bg_red, bg_green, bg_blue, emblem, emblem_red, i
emblem_green, emblem_blue, border, border_red, border_green, i
border_blue = GetInspectArenaTeamData(team)
Only available if data has been downloaded from the server; see
HasInspectHonorData() and RequestInspectHonorData().
Arguments:
teamIndex of one of the unit’s arena teams (number,arenaTeamID)
Returns:
teamNameName of the arena team (string)
teamSizeSize of the team (2 for 2v2, 3 for 3v3, or 5 for 5v5) (number)
teamRatingThe team’s current rating (number)
teamPlayedNumber of games played by the team in the current week
(number)
teamWinsNumber of games won by the team in the current week (number)
playerPlayedNumber of games in which the unit has participated in the cur-
rent week (number)
playerRatingThe unit’s personal rating with this team (number)
bg_redRed component of the color value for the team banner’s background
(number)
bg_greenGreen component of the color value for the team banner’s back-
ground (number)
bg_blueBlue component of the color value for the team banner’s background
(number)
emblemIndex of the team’s emblem graphic; full path to the emblem texture
can be found using the format “Interface\PVPFrame\Icons\PVP-Banner-
Emblem-“..emblem (number)
emblem_redRed component of the color value for the team banner’s emblem
(number)
emblem_greenGreen component of the color value for the team banner’s
emblem (number)
emblem_blueBlue component of the color value for the team banner’s
emblem (number)
Chapter 27 API Reference 713
borderIndex of the team’s border graphic; full path to the border texture
can be found by using the format “Interface\PVPFrame\PVP-Banner-“..
teamSize..“-Border-“..border (number)
border_redRed component of the color value for the team banner’s border
(number)
border_greenGreen component of the color value for the team banner’s bor-
der (number)
border_blueBlue component of the color value for the team banner’s border
(number)
GetInspectHonorData
Returns PvP honor information about the currently inspected unit.
todayHK, todayHonor, yesterdayHK, yesterdayHonor, lifetimeHK, i
lifetimeRank = GetInspectHonorData()
Only available if data has been downloaded from the server; see
HasInspectHonorData() and RequestInspectHonorData().
Returns:
todayHKNumber of honorable kills on the current day (number)
todayHonorAmount of honor points earned on the current day (number)
yesterdayHKNumber of honorable kills on the previous day (number)
yesterdayHonorAmount of honor points earned on the previous day
(number)
lifetimeHKLifetime total of honorable kills scored (number)
lifetimeRankHighest rank earned in the pre-2.0 PvP reward system;
see GetPVPRankInfo() for rank display information (number)
GetInstanceBootTimeRemaining
Returns the amount of time left until the player is removed from the current
instance.
timeleft = GetInstanceBootTimeRemaining()
Used when the player is in an instance he doesn’t own; e.g. if the player enters
an instance with a group and is then removed from the group.
Returns:
timeleftThe number of seconds until the player is booted from the current
instance (number)
GetInstanceDifficulty
Returns difficulty setting for the current dungeon/raid instance.
difficulty = GetInstanceDifficulty()
This returns the difficulty setting for the instance the player is currently in; not
to be confused with GetCurrentDungeonDifficulty(), which is the current
group’s setting for entering new instances, nor with GetDefault
DungeonDifficulty(), which is the player’s preference for dungeon
difficulty and may differ from that of the current party leader.
714 Part IV Reference
Returns:
difficultyThe current instance’s difficulty setting (number)
1Normal(5or10players)
2Heroic (5 players) / Normal (25 players)
3Heroic (10 players)
4Heroic (25 players)
Example:
-- Print your current difficulty setting
local difficulty = i
getglobal(“DUNGEON_DIFFICULTY“..GetInstanceDifficulty())
print(“Your dungeon difficulty is set to “ .. difficulty)
GetInstanceInfo
Returns instance information about the current area.
name, type, difficulty = GetInstanceInfo()
Returns:
nameName of the instance or world area (string)
typeType of the instance (string)
arenaA PvP Arena instance
noneNormal world area (e.g. Northrend, Kalimdor, Deeprun Tram)
partyAn instance for 5-man groups
pvpA PvP battleground instance
raidAn instance for raid groups
difficultyDifficulty setting of the instance (number)
1In raids, this represents 10 Player. In instances, Normal.
2In raids, this represents 25 Player. In instances, Heroic.
3In raids, this represents 10 Player Heroic. In instances, Epic
(unused for PvE instances but returned in some battlegrounds).
4In raids, this represents 25 Player Heroic. No corollary in instances.
GetInstanceLockTimeRemaining
Returns time remaining before the player is saved to a recently entered
instance.
seconds = GetInstanceLockTimeRemaining()
Applies when the player enters an instance to which other members of her
group are saved; if the player leaves the instance (normally or with
RespondInstanceLock(false)) within this time limit she will not be saved
to the instance.
Returns:
secondsTime remaining before the player is saved to the instance (number)
Chapter 27 API Reference 715
GetInventoryAlertStatus
Returns the durability warning status of an equipped item.
status = GetInventoryAlertStatus(slot)
Looking up the status returned by this function in the INVENTORY_ALERT
_COLORS table provides color values, used in the default UI to highlight parts
of the DurabiltyFrame (i.e. the ‘‘armored man’’ image) that appears when
durability is low.
Arguments:
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
Returns:
statusAlert status for the item in the given slot (number)
0No alert; the slot is empty, contains an item whose durability is
above critical levels, or contains an item without a durability value
1The item’s durability is dangerously low
2The item’s durability is at zero (the item is broken)
GetInventoryItemBroken
Returns whether an equipped item is broken.
isBroken = GetInventoryItemBroken(“unit“, slot)
Arguments:
unitA unit to query; only valid for ‘player’ or the unit currently being
inspected (string,unitID)
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
Returns:
isBroken1if the item is broken (durability zero); otherwise nil (1nil)
GetInventoryItemCooldown
Returns cooldown information about an equipped item.
start, duration, enable = GetInventoryItemCooldown(“unit“, slot)
Arguments:
unitA unit to query; only valid for ‘player’ (string,unitID)
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
Returns:
start—The value of GetTime() at the moment the cooldown began, or 0 if the
item is ready (number)
durationThe length of the cooldown, or 0 if the item is ready (number)
enable1if a Cooldown UI element should be used to display the cooldown,
otherwise 0. (Does not always correlate with whether the item is ready.)
(number)
716 Part IV Reference
GetInventoryItemCount
Returns the number of items stacked in an inventory slot.
count = GetInventoryItemCount(“unit“, slot)
Currently only returns meaningful information for the ammo slot.
Arguments:
unitA unit to query; only valid for ‘player’ or the unit currently being
inspected (string,unitID)
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
Returns:
countThe amount of items stacked in the inventory slot (number)
GetInventoryItemDurability
Returns the current durability level of an equipped item.
durability, max = GetInventoryItemDurability(slot)
Arguments:
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
Returns:
durabilityThe item’s current durability (number)
maxThe item’s maximum durability (number)
Example:
-- Query HeadSlot durability
local slot = GetInventorySlotInfo(“HeadSlot“)
local durability,max = GetInventoryItemDurability(slot)
print(“Head armor is currently at“, durability, “of“, max, “durability“)
GetInventoryItemGems
Returns the gems socketed in an equipped item.
gem1, gem2, gem3 = GetInventoryItemGems(slot)
The IDs returned refer to the gems themselves (not the enchantments they
provide), and thus can be passed to GetItemInfo() to get a gem’s name,
quality, icon, etc.
Arguments:
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
Returns:
gem1Item ID of the first gem socketed in the item (itemID)
gem2Item ID of the second gem socketed in the item (itemID)
gem3Item ID of the third gem socketed in the item (itemID)
Chapter 27 API Reference 717
GetInventoryItemID
Returns the item ID of an equipped item.
id = GetInventoryItemID(“unit“, slot)
Arguments:
unitA unit to query; only valid for ‘player’ or the unit currently being
inspected (string,unitID)
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
Returns:
idNumeric ID of the item in the given slot (itemID)
GetInventoryItemLink
Returns an item link for an equipped item.
link = GetInventoryItemLink(“unit“, slot)
Arguments:
unitA unit to query; only valid for ‘player’ or the unit currently being
inspected (string,unitID)
slotAn inventory slot number, as can be obtained from GetInventorySlot
Info (number,inventoryID)
Returns:
linkAn item link for the given item (string, hyperlink)
GetInventoryItemQuality
Returns the quality level of an equipped item.
quality = GetInventoryItemQuality(“unit“, slot)
Arguments:
unitA unit to query; only valid for ‘player’ or the unit currently being
inspected (string,unitID)
slotAn inventory slot number, as can be obtained from GetInventorySlot
Info (number,inventoryID)
Returns:
qualityThe quality level of the item (number, itemQuality)
GetInventoryItemTexture
Returns the icon texture for an equipped item.
texture = GetInventoryItemTexture(“unit“, slot)
Arguments:
unitA unit to query; only valid for ‘player’ or the unit currently being
inspected (string,unitID)
slotAn inventory slot number, as can be obtained from GetInventorySlot
Info (number,inventoryID)
Returns:
texturePathtoanicontexturefortheitem(string)
718 Part IV Reference
GetInventoryItemsForSlot
Returns a list of items that can be equipped in a given inventory slot.
availableItems = GetInventoryItemsForSlot(slot)
Arguments:
slotAn inventory slot number, as can be obtained from GetInventorySlot
Info (number,inventoryID)
Returns:
availableItemsA table listing itemIDsofitemswhichcan
be equipped in the slot, keyed by itemLocation (table)
GetInventorySlotInfo
Returns information about an inventory slot.
id, texture, checkRelic = GetInventorySlotInfo(“slotName“)
Arguments:
slotNameName of an inventory slot to query (string)
AmmoSlotRanged ammunition slot
BackSlotBack (cloak) slot
Bag0SlotBackpack slot
Bag1SlotFirst bag slot
Bag2SlotSecond bag slot
Bag3Slot—Third bag slot
ChestSlotChest slot
FeetSlotFeet (boots) slot
Finger0SlotFirst finger (ring) slot
Finger1SlotSecond finger (ring) slot
HandsSlotHand (gloves) slot
HeadSlotHead (helmet) slot
LegsSlotLegs (pants) slot
MainHandSlotMain hand weapon slot
NeckSlot—Necklace slot
RangedSlotRanged weapon or relic slot
SecondaryHandSlotOff-hand (weapon, shield, or held item) slot
ShirtSlotShirt slot
ShoulderSlotShoulder slot
TabardSlotTabard slot
Trinket0SlotFirst trinket slot
Trinket1SlotSecond trinket slot
WaistSlotWaist (belt) slot
WristSlotWrist (bracers) slot
Returns:
idThe numeric slotId usable in other Inventory functions (number)
Chapter 27 API Reference 719
textureThe path to the texture to be displayed when this slot is empty
(string)
checkRelic1if the slot might be the relic slot; otherwise nil. The ranged
slot token is re-used for the relic slot; if this return is 1, UnitHasRelicSlot
should be used to determine how the slot should be displayed. (1nil)
GetItemCooldown
Returns cooldown information about an arbitrary item.
start, duration, enable = GetItemCooldown(itemID) or i
GetItemCooldown(“itemName“) or GetItemCooldown(“itemLink“)
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Returns:
start—The value of GetTime() at the moment the cooldown began, or 0 if the
item is ready (number)
durationThe length of the cooldown, or 0 if the item is ready (number)
enable1if a Cooldown UI element should be used to display the cooldown,
otherwise 0. (Does not always correlate with whether the item is ready.)
(number)
GetItemCount
Returns information about how many of a given item the player has or on
remaining item charges.
itemCount = GetItemCount(itemId, includeBank, includeCharges) or i
GetItemCount(“itemName“, includeBank, includeCharges) or i
GetItemCount(“itemLink“, includeBank, includeCharges)
When the third argument includeCharges is true, the returned number
indicates the total number of remaining charges for the item instead of how
many of the item you have; e.g. if you have 3 Wizard Oils and one of them has
been used twice, the returned value will be 13.
Arguments:
itemId—An item id (number)
itemName—An item name (string)
itemLinkAn item link (string)
includeBanktrue to include items in the bank in the returned count, other-
wise false (boolean)
includeChargestrue to count charges for applicable items, otherwise false
(boolean)
Returns:
itemCountThe number of the given item the player has in possession (possi-
bly including items in the bank), or the total number of charges on those items
(number)
720 Part IV Reference
Example:
_, link = GetItemInfo(“Hearthstone“)
GetItemCount(link)
-- nearly always returns 1 for most players
GetItemCount(34722, true) - GetItemCount(34722)
-- returns number of Heavy Frostweave Bandages in the player’s
-- bank (not counting those on hand)
GetItemCount(“Drums of Speed“, nil, true)
-- return of 99 could indicate player has two drums in inventory,
-- one of which has been used only once
GetItemFamily
Returns information about special bag types that can hold a given item.
bagType = GetItemFamily(itemID) or GetItemFamily(“itemName“) or i
GetItemFamily(“itemLink“)
The meaning of bagType varies depending on the item:
If the item is a container, bagType indicates which kinds of items the con-
tainer is limited to holding; a bagType of 0 indicates the container can hold
any kind of item.
If the item is not a container, bagType indicates which kinds of
specialty containers can hold the item; a bagType of 0 indicates
the item can only be put in general-purpose containers.
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Returns:
bagTypeBitwise OR of bag type flags: (number, bitfield)
0x0001—Quiver
0x0002Ammo Pouch
0x0004—Soul Bag
0x0008Leatherworking Bag
0x0010—Inscription Bag
0x0020—Herb Bag
0x0040Enchanting Bag
0x0080Engineering Bag
0x0100—Keyring
0x0200—Gem Bag
0x0400Mining Bag
0x0800—Unused
0x1000—Vanity Pets
Example:
function CanGoInBag(item, bag)
-- Get the item’s family
local itemFamily = GetItemFamily(item)
-- If the item is a container, then the itemFamily should be 0
Chapter 27 API Reference 721
local equipSlot = select(9, GetItemInfo(item))
if equipSlot == “INVTYPE_BAG“ then
itemFamily = 0
end
-- Get the bag’s family
local bagFamily = select(2, GetContainerNumFreeSlots(bag))
return bagFamily == 0 or bit.band(itemFamily, bagFamily) > 0
end
GetItemGem
Returns information about gems socketed in an item.
name, link = GetItemGem(itemID, index) or i
GetItemGem(“itemName“, index) or GetItemGem(“itemLink“, index)
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
indexIndex of a socket on the item (number)
Returns:
nameName of the gem in the socket (string)
linkA hyperlink for the gem in the socket (string, hyperlink)
GetItemIcon
Returns the path to an icon texture for the item.
texture = GetItemIcon(itemID) or GetItemIcon(“itemName“) or i
GetItemIcon(“itemLink“)
Unlike GetItemInfo, this function always returns icons for valid items, even if
the item is not in the client’s cache.
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Returns:
texturePathtoanicontexturefortheitem(string)
GetItemInfo
Returns information about an item, by name, link or id.
name, link, quality, iLevel, reqLevel, class, subclass, maxStack, i
equipSlot, texture, vendorPrice = GetItemInfo(itemID) or i
GetItemInfo(“itemName“) or GetItemInfo(“itemLink“)
Only returns information for items in the WoW client’s local cache; returns nil
for items the client has not seen.
722 Part IV Reference
Arguments:
itemID—An items ID (number,itemID)
itemNameAn item’s name. This value will only work if the player has the
item in their bags. (string)
itemLinkAn item’s hyperlink, or any string containing the itemString
portion of an item link (string)
Returns:
name—Name of the item (string)
linkA hyperlink for the item (string, hyperlink)
qualityQuality (rarity) level of the item. (number, itemQuality)
iLevelInternal level of the item; (number)
reqLevelMinimum character level required to use or equip the item
(number)
classLocalized name of the item’s class/type (as in the list returned by
GetAuctionItemClasses())(string)
subclassLocalized name of the item’s subclass/subtype (as in the
list returned by GetAuctionItemSubClasses())(string)
maxStackMaximum stack size for the item (i.e. largest num-
ber of items that can be held in a single bag slot) (number)
equipSlotNon-localized token identifying the inventory type of the item
(as in the list returned by GetAuctionItemInvTypes()); name of a global
variable containing the localized name of the inventory type (string)
texturePathtoanicontexturefortheitem(string)
vendorPricePrice an NPC vendor will pay to buy the item
from the player. This value was added in patch 3.2. (number)
GetItemQualityColor
Returns color values for use in displaying items of a given quality.
redComponent, greenComponent, blueComponent, hexColor = i
GetItemQualityColor(quality)
Color components are floating-point values between 0 (no component) and 1
(full intensity of the component).
Arguments:
qualityAn numeric item quality (rarity) value (number, itemQuality)
Returns:
redComponentRed component of the color (number)
greenComponentGreen component of the color (number)
blueComponentBlue component of the color (number)
hexColor—Prex of a colorString for formatting text with the color
(string)
Example:
GetItemQualityColor(4)
-- returns (approximately) 0.6392, 0.2078, 0,9333, “|cffa335ee“
Chapter 27 API Reference 723
GetItemSpell
Returns information about the spell cast by an item’s ‘‘Use:’’ effect.
name, rank = GetItemSpell(itemID) or GetItemSpell(“itemName“) or i
GetItemSpell(“itemLink“)
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Returns:
nameName of the spell (string)
rankSecondary text associated with the spell (often a rank, e.g. ‘‘Rank 7’’); or
the empty string (““) if not applicable (string)
GetItemStatDelta
Returns a summary of the difference in stat bonuses between two items.
statTable = GetItemStatDelta(“item1Link“, “item2Link“ [, returnTable])
Keys in the table returned are the names of global variables containing the
localized names of the stats (e.g. _G[“ITEM_MOD_SPIRIT_SHORT“] =
“Spirit“,_G[“ITEM_MOD_HIT_RATING_SHORT“] = “Hit Rating“).
The optional argument returnTable allows for performance optimization in
cases where this function is expected to be called repeatedly. Rather than
creating new tables each time the function is called (eventually requiring
garbage collection), an existing table can be recycled. (Note, however, that this
function does not clear the table’s contents; use wipe() first to guarantee
consistent results.)
Arguments:
item1LinkAn item’s hyperlink, or any string containing the itemString
portion of an item link (string, hyperlink)
item2LinkAnother item’s hyperlink, or any string containing
the itemString portion of an item link (string, hyperlink)
returnTable (optional)Reference to a table to be filled with return values
(table)
Returns:
statTableA table listing the difference in stat bonuses provided
by the items (i.e. if item1Link is equipped, what changes to the
player’s stats would occur if it is replaced by item2Link)(table)
Example:
-- links to some early death knight gear for illustrating the example...
local _, ring1Link = GetItemInfo(“Valanar’s Signet Ring“)
local _, ring2Link = GetItemInfo(“Keleseth’s Signet Ring“)
local statDelta = GetItemStatDelta(ring1Link, ring2Link)
724 Part IV Reference
for stat, value in pairs(statDelta) do print(value, _G[stat]) end
-- prints (approximately, on enUS client):
-- 12 Critical Strike Rating
-- -6 Strength
-- -6 Hit Rating
-- 3 Stamina
GetItemStats
Returns a summary of an item’s stat bonuses.
statTable = GetItemStats(“itemLink“ [, returnTable])
Keys in the table returned are the names of global variables containing the
localized names of the stats (e.g. _G[“ITEM_MOD_SPIRIT_SHORT“] =
“Spirit“,_G[“ITEM_MOD_HIT_RATING_SHORT“] = “Hit Rating“).
The optional argument returnTable allows for performance optimization in
cases where this function is expected to be called repeatedly. Rather than
creating new tables each time the function is called (eventually requiring
garbage collection), an existing table can be recycled. (Note, however, that this
function does not clear the table’s contents; use wipe() first to guarantee
consistent results.)
Arguments:
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string, hyperlink)
returnTable (optional)Reference to a table to be filled with return values
(table)
Returns:
statTableA table listing the stat bonuses provided by the item (table)
Example:
-- links to some early death knight gear for illustrating the example...
local _, swordLink = GetItemInfo(“Greatsword of the Ebon Blade“)
local _, ring1Link = GetItemInfo(“Valanar’s Signet Ring“)
local stats = GetItemStats(swordLink)
for stat, value in pairs(stats) do print(value, _G[stat]) end
-- prints (approximately, on enUS client):
-- 60.5 Damage Per Second
-- 30 Strength
-- 12 Hit Rating
-- 24 Stamina
-- reusing the table...
GetItemStats(ring1Link, stats)
for stat, value in pairs(stats) do print(value, _G[stat]) end
-- 60.5 Damage Per Second
-- 12 Strength
-- 12 Hit Rating
-- 12 Critical Strike Rating
Chapter 27 API Reference 725
-- 18 Stamina
-- oops, it overwrote the table from before, keeping some
-- of the sword’s stats...
-- let’s try again and make sure it shows just the ring stats
wipe(stats)
GetItemStats(ring1Link, stats)
for stat, value in pairs(stats) do print(value, _G[stat]) end
-- 12 Strength
-- 12 Critical Strike Rating
-- 18 Stamina
GetItemUniqueness
Returns information about uniqueness restrictions for equipping an item.
uniqueFamily, maxEquipped = GetItemUniqueness(itemID) or i
GetItemUniqueness(“itemName“) or GetItemUniqueness(“itemLink“)
Only applies to items with ‘‘Unique Equipped’’ restrictions upon how many
similar items can be equipped; returns nil for items which for which ‘‘Unique’’
restricts how many the player can have in her possession.
Also returns nil if the queried item is not currently in the WoW client’s item
cache.
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s link (string)
Returns:
uniqueFamilyThe family of items with special uniqueness restrictions to
which the item belongs (number)
maxEquippedThe maximum number of items under this restriction that can
be equipped (number)
Example:
GetItemUniqueness(“Rigid Dragon’s Eye“)
-- returns 2, 3 if your WoW client has seen this gem
-- up to 3 gems in the Jeweler’s Gems family can be equipped
-- at any given time
GetItemUniqueness(“Rigid Stormjewel“)
-- returns 6, 1 if your WoW client has seen this gem
-- only 1 gem in the Stormjewel family can be equipped at any given time
GetItemUniqueness(“Figurine - Ruby Hare“)
-- returns -1, 1 if your WoW client has seen this item
-- only 1 Ruby Hare can be equipped at any given time
GetKnownSlotFromHighestRankSlot
Returns the spellbook slot for the player’s highest known rank of a spell.
maxRankSlot = GetKnownSlotFromHighestRankSlot(slot)
Arguments:
slotSpellbook slot index of a known spell (number)
726 Part IV Reference
Returns:
maxRankSlotSpellbook slot index of the highest rank of that spell known to
the player (number)
GetLFGPartyResults
Returns information about a member of a party in Looking for More results.
name, level, class, zone, comment, leader, tank, healer, damage = i
GetLFGPartyResults(type, name, index, partyIndex)
Can be used when the 9th return (numPartyMembers)fromGetLFGResults()
is 1 or greater. The default UI uses this return to segregate results into separate
‘‘Individuals’’ and ‘‘Groups’’ lists, and this function is used to populate the
group members tooltip that appears when mousing over a group listing.
Arguments:
typeIndex of an LFG query type (in the list returned by GetLFGTypes())
(number)
nameIndex of an LFG entry (in the list returned by GetLFGTypeEntries
(type))(number)
indexIndex of a result in the Looking for More listing (between 1and
GetNumLFGResults(type,name))(number)
partyIndexIndex of a party member, not counting the party leader (between
1and select(9, GetLFGResults(type,name,index)))(number)
Returns:
name—Name of the party member (string)
levelParty member’s character level (string)
classLocalized name of the party member’s class (string)
zoneThe character’s current location (string)
commentBrief text comment supplied by the character (string)
leaderTrue if the character is willing to lead a group; otherwise false
(boolean)
tankTrue if the character is willing to take on the role of protecting
allies by drawing enemy attacks; otherwise false (boolean)
healerTrue if the character is willing to take on the role of healing allies who
take damage; otherwise false (boolean)
damageTrue if the character is willing to take on the role of damaging ene-
mies; otherwise false (boolean)
GetLFGResults
Returns information about a character in the Looking for More results listing.
name, level, zone, class, criteria1, criteria2, criteria3, comment, i
numPartyMembers, isLFM, classFileName, leader, tank, healer, damage, i
bossKills, talent1, talent2, talent3, isLeader, isAutoJoin, armor, i
damage, healing, meleeCrit, rangedCrit, spellCrit, manaRegen, i
manaCombatRegen, attackPower, agility, maxHealth, maxPower, i
avgGearRating, defense, dodge, block, parry, haste, expertise = i
GetLFGResults(type, name, index)
Chapter 27 API Reference 727
The default UI uses the 9th return from this function (numPartyMembers)to
segregate results into separate ‘‘Individuals’’ and ‘‘Groups’’ lists for display,
but at the API level these are combined into a single listing.
Arguments:
typeIndex of an LFG query type (in the list returned by GetLFGTypes())
(number)
nameIndex of an LFG entry (in the list returned by GetLFGTypeEntries
(type))(number)
indexIndex of a result in the Looking for More listing (between 1and
GetNumLFGResults(type,name))(number)
Returns:
nameName of the character (string)
levelThe character’s (number)
zoneThe character’s current location (string)
classLocalized name of the character’s class (string)
criteria1Name of the character’s first LFG objective (string)
criteria2Name of the character’s second LFG objective; nil if not applica-
ble (string)
criteria3Name of the character’s third LFG objective; nil if not applicable
(string)
commentBrief text comment supplied by the character (string)
numPartyMembersNumber of additional members in the character’s party
(number)
isLFMtrue if the player is looking for more members; otherwise false
(boolean)
classFileNameNon-localized token representing the character’s class
(string)
leaderTrue if the character is willing to lead a group; otherwise false
(boolean)
tankTrue if the character is willing to take on the role of protecting
allies by drawing enemy attacks; otherwise false (boolean)
healerTrue if the character is willing to take on the role of healing allies who
take damage; otherwise false (boolean)
damageTrue if the character is willing to take on the role of damaging ene-
mies; otherwise false (boolean)
bossKillsThe number of boss kills the player has. (number)
talent1The number of talent points spent in the player’s first talent tree.
(number)
talent2The number of talent points spent in the player’s second talent tree.
(number)
talent3The number of talent points spent in the player’s third talent tree.
(number)
728 Part IV Reference
isLeaderWhether or not the player is willing to lead a group. (boolean)
isAutoJoinWhether or not the player is set to automatically join groups.
(boolean)
armorThe player’s armor rating. (number)
damageThe player’s damage rating. (number)
healingThe player’s healing rating. (number)
meleeCritThe player’s melee crit rating. (number)
rangedCritThe player’s ranged crit rating. (number)
spellCritThe player’s spell crit rating. (number)
manaRegenThe player’s out of combat mana regen. (number)
manaCombatRegenThe player’s in-combat mana regen. (number)
attackPowerThe player’s attack power rating. (number)
agilityThe player’s agility rating. (number)
maxHealthThe player’s maximum health. (number)
maxPowerThe player’s maximum power. (number)
avgGearRatingThe player’s average gear rating (out of 100). (number)
defenseThe player’s defense rating. (number)
dodgeThe player’s dodge rating. (number)
blockThe player’s block rating. (number)
parryThe player’s parry rating. (number)
hasteThe player’s haste rating. (number)
expertiseThe player’s expertise rating. (number)
GetLFGRoles
Returns the group roles for which the player has signed up in the LFG system.
leader, tank, healer, damage = GetLFGRoles()
Returns:
leaderTrue if the player is willing to lead a group; otherwise false
(boolean)
tankTrue if the player is willing to take on the role of protecting
allies by drawing enemy attacks; otherwise false (boolean)
healerTrue if the player is willing to take on the role of healing allies who
take damage; otherwise false (boolean)
damageTrue if the player is willing to take on the role of damaging enemies;
otherwise false (boolean)
GetLFGStatusText
Returns information about the player’s status in the LFG auto-join or LFM
auto-fill queues.
isLFG, numCriteria, ... = GetLFGStatusText()
Does not return useful information if the player is not queued to automatically
join or fill a group.
Chapter 27 API Reference 729
Returns:
isLFGtrue if the character is looking for group, false if looking for more
(boolean)
numCriteriaNumber of additional values returned following this one
(number)
...A list of strings, each the name of an LFG entry for which the player is
queued (list)
GetLFGTypeEntries
Returns a list of LFG entries (dungeons, zones, quests, etc) for a given type.
name, icon, ... = GetLFGTypeEntries(type)
Arguments:
typeIndex of an LFG query type (in the list returned by GetLFGTypes())
(number)
Returns:
nameLocalized name of the entry (string)
iconUnique part of the path to an icon texture for the entry; prepend
“Interface\\LFGFrame\\LFGIcon-“ for the full path (string)
...An additional name, icon pair for each entry in the list (list)
GetLFGTypes
Returns a list of LFG query types.
... = GetLFGTypes()
Returns:
...A list of strings, each the localized name of an LFG type (Dungeon, Raid,
Zone, etc.) (list)
GetLanguageByIndex
Returns the localized name of a player character language.
language = GetLanguageByIndex(index)
Arguments:
indexIndex of a player character language (between 1and GetNum
Languages() (number)
Returns:
languageLocalized name of the language (e.g. ‘‘Common’’ or ‘‘Gnomish’’)
(string)
GetLatestCompletedAchievements
Returns a list of the player’s most recently earned achievements.
... = GetLatestCompletedAchievements()
Returns:
...A list of up to five numeric IDs of recently earned achievements, ordered
from newest to oldest (list)
730 Part IV Reference
GetLatestCompletedComparisonAchievements
Returns a list of the comparison unit’s most recently earned achievements.
... = GetLatestCompletedComparisonAchievements()
Returns:
...A list of up to five numeric IDs of recently earned achievements, ordered
from newest to oldest (list)
GetLatestThreeSenders
Returns the names of the last three senders of new mail.
sender1, sender2, sender3 = GetLatestThreeSenders()
Returns sender names for new messages which the player has not yet seen in
the mailbox; returns nothing if the player’s inbox only contains unread
messages which have been seen in the mailbox listing but not yet opened.
Returns:
sender1Name of a recent message’s sender (string)
sender2Name of a recent message’s sender (string)
sender3Name of a recent message’s sender (string)
GetLocale
Returns a code indicating the localization currently in use by the client.
locale = GetLocale()
Returns:
localeA four character locale code indicating the localization currently in use
by the client (string)
deDE—German
enGBBritish English
enUSAmerican English
esESSpanish (European)
esMXSpanish (Latin American)
frFR—French
koKR—Korean
ruRURussian
zhCNChinese (simplified; mainland China)
zhTWChinese (traditional; Taiwan)
GetLookingForGroup
Returns information about the player’s status in the LFG system.
type1, name1, type2, name2, type3, name3, lfmType, lfmName, comment, i
queued, lfgStatus, lfmStatus, autoAdd = GetLookingForGroup()
Returns:
type1Index of the LFG query type for the player’s first objective (in the list
returned by GetLFGTypes())(number)
Chapter 27 API Reference 731
name1Index of the LFG entry for the player’s first objective (in
the list returned by GetLFGTypeEntries(type1))(number)
type2Index of the LFG query type for the player’s second objective (number)
name2Index of the LFG entry for the player’s second objective (number)
type3IndexoftheLFGquerytypefortheplayersthirdobjective(number)
name3Index of the LFG entry for the player’s third objective (number)
lfmTypeIndex of an LFG query type for the player’s current Looking for More
query (number)
lfmNameIndex of an LFG entry for the player’s current Looking for More
query (number)
commentBrief text to be seen by others when viewing the player’s LFG adver-
tisement (string)
queuedtrue if the player is queued to automatically join a group; otherwise
false (boolean)
lfgStatustrue if the player is looking for a group; otherwise false
(boolean)
lfmStatustrue if the player is looking for more players for his or her group;
otherwise false (boolean)
autoAddtrue if the player has chosen to automatically add members to his or
her group; otherwise false (boolean)
GetLootMethod
Returns information about the current loot method in a party or raid.
method, partyMaster, raidMaster = GetLootMethod()
Only returns useful information if the player is in a party or raid.
Returns:
methodCurrent loot method (string)
freeforallFree for All: any group member can take any loot at any time
groupGroup Loot: like Round Robin, but items above a quality threshold
are rolled on
masterMaster Looter: like Round Robin, but items above
a quality threshold are left for a designated loot master
needbeforegreedNeed before Greed: like Group Loot, but members auto-
matically pass on items
roundrobinRound Robin: group members take turns being able to loot
partyMasterNumeric portion of the party unitID of the loot master (e.g.
if 2, the loot master’s unitID is party2); nil if not using the Master Looter
method or if the player is in a raid whose loot master is not in the player’s
subgroup. If the player is the master looter, this value will return 0 (number)
raidMasterNumeric portion of the raid unitID of the loot mas-
ter (e.g. if 17, the loot master’s unitID is raid17); nil if not using
the Master Looter method or not in a raid group (number)
732 Part IV Reference
GetLootRollItemInfo
Returns information about an item currently up for loot rolling.
texture, name, count, quality, bindOnPickUp = GetLootRollItemInfo(id)
Arguments:
idIndex of an item currently up for loot rolling (as provided in the
START_LOOT_ROLL event) (number)
Returns:
texturePathtoanicontexturefortheitem(string)
name—Name of the item (string)
countNumber of stacked items (number)
qualityQuality (rarity) of the item. (number, itemQuality)
bindOnPickUp1if the item is bind on pickup; otherwise nil (1nil)
GetLootRollItemLink
Returns a hyperlink for an item currently up for loot rolling.
link = GetLootRollItemLink(id)
Arguments:
idIndex of an item currently up for loot rolling (as provided in the
START_LOOT_ROLL event) (number)
Returns:
linkA hyperlink for the loot roll item (string, hyperlink)
GetLootRollTimeLeft
Returns the amount of time remaining before loot rolling for an item expires.
timeLeft = GetLootRollTimeLeft(id)
When the time expires, all group members who have not yet chosen to roll
Need or Greed automatically pass, random roll results are produced for those
who chose to roll, and the server declares a winner and awards the item.
Arguments:
idIndex of an item currently up for loot rolling (as provided in the
START_LOOT_ROLL event) (number)
Returns:
timeLeftAmount of time remaining before loot rolling for the item expires
(in milliseconds) (number)
GetLootSlotInfo
Returns a hyperlink for an item available as loot.
texture, item, quantity, quality, locked = GetLootSlotInfo(slot)
Arguments:
slotIndex of a loot slot (between 1and GetNumLootItems())(number)
Returns:
texturePath to an icon texture for the item or amount of money (string)
itemName of the item, or description of the amount of money (string)
Chapter 27 API Reference 733
quantityNumber of stacked items, or 0 for money (number)
qualityQuality (rarity) of the item (number, itemQuality)
locked1if the item is locked (preventing the player from looting it); other-
wise nil (1nil)
GetLootSlotLink
Returns a hyperlink for an item available as loot.
link = GetLootSlotLink(slot)
Returns nil if the loot slot is empty or contains money.
Arguments:
slotIndex of a loot slot (between 1and GetNumLootItems())(number)
Returns:
linkA hyperlink for the item (string)
GetLootThreshold
Returns the threshold used for Master Looter, Group Loot, and Need Before
Greed loot methods.
threshold = GetLootThreshold()
Items above the threshold quality will trigger the special behavior of the
current loot method: for Group Loot and Need Before Greed, rolling will
automatically begin once a group member loots the corpse or object holding
the item; for Master Loot, the item will be invisible to all but the loot master
tasked with assigning the loot.
Returns:
thresholdMinimum item quality to trigger the loot method (number,
itemQuality)
GetMacroBody
Returns the body text of a macro.
body = GetMacroBody(index) or GetMacroBody(“name“)
Arguments:
index—Index of a macro (number,macroID)
name—Name of a macro (string)
Returns:
bodyBody text / commands of the macro (string)
GetMacroIconInfo
Returns the texture for a macro icon option.
texture = GetMacroIconInfo(index)
Arguments:
indexIndex of a macro icon option (between 1and GetNumMacroIcons())
(number)
Returns:
texture—Path to the icon texture (string)
734 Part IV Reference
GetMacroIndexByName
Returns the index of a macro specified by name.
index = GetMacroIndexByName(“name“)
Arguments:
name—Name of a macro (string)
Returns:
indexIndex of the named macro, or 0 if no macro by that name exists
(number,macroID)
GetMacroInfo
Returns information about a macro.
name, texture, body = GetMacroInfo(index) or GetMacroInfo(“name“)
Arguments:
index—Index of a macro (number,macroID)
name—Name of a macro (string)
Returns:
name—Name of the macro (string)
texturePathtoanicontextureforthemacro(string)
bodyBody text / commands of the macro (string)
GetMacroItem
Returns information about the item used by a macro.
name, link = GetMacroItem(index) or GetMacroItem(“name“)
If a macro contains conditional, random, or sequence commands, this function
returns the item which would currently be used if the macro were run.
Arguments:
index—Index of a macro (number,macroID)
name—Name of a macro (string)
Returns:
name—Name of the item (string)
linkA hyperlink for the item (string, hyperlink)
Example:
CreateMacro(“health“,1,“/use [combat] Runic Healing Potion ; i
[nocombat] Salted Venison“)
-- when in combat:
GetMacroItem(“health“)
-- returns “Runic Healing Potion“ (and hyperlink)
-- when not in combat:
GetMacroItem(“health“)
-- returns “Salted Venison“ (and hyperlink)
GetMacroItemIconInfo
Returns the texture for an item icon.
texture = GetMacroItemIconInfo(index)
Chapter 27 API Reference 735
Despite the ‘‘macro’’ in the title, this function is only used by the default UI for
providing tab icon options in the guild bank.
Arguments:
indexIndex of an item icon option (between 1and GetNumMacroItem
Icons())(number)
Returns:
texture—Path to the icon texture (string)
GetMacroSpell
Returns information about the spell cast by a macro.
name, rank = GetMacroSpell(index) or GetMacroSpell(“name“)
If a macro contains conditional, random, or sequence commands, this function
returns the spell which would currently be cast if the macro were run.
Arguments:
index—Index of a macro (number,macroID)
name—Name of a macro (string)
Returns:
nameName of the spell (string)
rankSecondary text associated with the spell (e.g. ‘‘Rank 4’’, ‘‘Racial’’)
(string)
Example:
CreateMacro(“fort“,1,“/cast [party] Prayer of Fortitude ; [noparty] i
Power Word: Fortitude“)
-- when in a party:
GetMacroSpell(“fort“)
-- returns “Prayer of Fortitude“, “Rank 3“
-- when not in combat:
GetMacroSpell(“fort“)
-- returns “Power Word: Fortitude“, “Rank 7“
GetManaRegen
Returns information about the player’s mana regeneration rate.
base, casting = GetManaRegen()
Returns:
baseAmount of mana regenerated per second while not casting (number)
castingAmount of mana regenerated per second while casting (number)
GetMapContinents
Returns a list of map continents names.
... = GetMapContinents()
Returns:
...A list of strings, each the localized name of a map continent (list)
736 Part IV Reference
GetMapInfo
Returns information about the current world map texture.
mapFileName, textureHeight, textureWidth = GetMapInfo()
World map images are broken into several tiles; the full texture paths follow
the format
“Interface\\WorldMap\\“..mapFileName..“\\“..mapFileName..i,
where iis a number between 1 and NUM_WORLDMAP_DETAIL_TILES (or in a
zone with multiple area images,
“Interface\\WorldMap\\“..mapFileName..“\\“..mapFileName..
dungeonLevel..“_“..i,wheredungeonLevel is a number between 1 and
GetNumDungeonMapLevels()).
Returns:
mapFileNameUnique part of the path to the world map textures (string)
textureHeightHeight of the combined map texture tiles (number)
textureWidthWidth of the combined map texture tiles (string)
GetMapLandmarkInfo
Returns information about a map landmark.
name, description, textureIndex, x, y, mapLinkID, showInBattleMap = i
GetMapLandmarkInfo(index)
Possible landmarks include PvP objectives (both in battlegrounds and in world
PvP areas), town and city markers on continent maps, and special markers
such as those used during the Scourge Invasion world event. Some landmarks
(such as those for towns on a zone map) exist but are not visible in the default
UI.
Arguments:
indexThe index of a map landmark, from 1to GetNumMapLandmarks()
(number)
Returns:
nameName of the landmark (string)
descriptionSecondary text associated with the landmark; often used to
denote current status of PvP objectives (e.g. ‘‘Alliance Controlled’’) (string)
textureIndexThe index of the texture to be used for the landmark.
These indices map to segments of the Interface/MinimapPOI/Icons.blp
graphic; the function WorldMap_GetPOITextureCoords(), defined
in FrameXML/WorldMap.lua, can be used to resolve this index to a
set of texture coordinates for displaying that segment. (number)
xHorizontal position of the landmark relative to the current world map (0 =
left edge, 1=right edge) (number)
yVertical position of the landmark relative to the current world map (0 =top,
1=bottom) (number)
mapLinkIDA hyperlink ID allowing the game engine to take an
action when the landmark is clicked (currently unused) (number)
Chapter 27 API Reference 737
showInBattleMapTrue if the landmark should be shown in the Battle Map
(aka Zone Map) UI; false for landmarks which should only be shown on the
World Map (boolean)
GetMapOverlayInfo
Returns information about a world map overlay.
textureName, textureWidth, textureHeight, offsetX, offsetY, i
mapPointX, mapPointY = GetMapOverlayInfo(index)
Map overlays correspond to areas which are ‘‘discovered’’ when entered by
the player, ‘‘filling in’’ the blank areas of the world map.
Arguments:
indexIndex of a map overlay (between 1and GetNumMapOverlays())
(number)
Returns:
textureNamePath to the overlay texture (string)
textureWidthWidth of the texture (in pixels) (number)
textureHeightHeight of the texture (in pixels) (number)
offsetXHorizontal position of the overlay’s top left corner rela-
tive to the zone map (0 =left edge, 1=right edge) (number)
offsetYVertical position of the overlay’s top left corner relative to the zone
map (0 =top, 1=bottom) (number)
mapPointX—Unused (number)
mapPointY—Unused (number)
GetMapZones
Returns the map zones for a given continent.
... = GetMapZones(continentIndex)
Arguments:
continentIndexIndex of a continent (in the list returned by
GetMapContinents())(number)
Returns:
...A list of strings, each the localized name of a zone within the continent
(list)
Example:
local continent = GetCurrentMapContinent()
local zones = {GetMapZones(continent)}
for idx,zone in ipairs(zones) do
print(“Zone #“..idx .. “: “ .. zone)
end
GetMasterLootCandidate
Returns information about a given loot candidate.
candidate = GetMasterLootCandidate(index)
Used in the default UI to build the popup menu used in master loot
assignment. Only valid if the player is the master looter.
738 Part IV Reference
Not all party/raid members may be eligible for a given corpse’s (or object’s)
loot: e.g. a member is ineligible for loot from a creature killed while that
member was not in the immediate area. By repeatedly calling this function
(with index incrementing from 1 to the total number of party/raid members,
including the player), one can build a list of the names of members eligible for
the current loot.
The index is cast in stone at the time the mob was killed. If you move raid
members around prior to distributing loot, their original positions will be
returned by this function. The expression ceil(index/5) will yield the
group number (in a raid) and the expression index % 5 will yield the group
position number for an eligible raider.
Arguments:
indexIndex of a member of the party or raid (*not* equivalent
to the numeric part of a party or raid unitID)(number)
Returns:
candidateName of the candidate (string)
Example:
for i=1,40 do
local grp = ceil(i / 5)
local slot = i % 5
local raider = GetMasterLootCandidate (i)
if (raider) then
print (string.format(“Raider %q (group %d, position %d) is i
eligible for loot.“, raider, grp, slot))
end
end
GetMaxArenaCurrency
Returns the maximum amount of arena points the player can accrue.
amount = GetMaxArenaCurrency()
Returns:
amountThe maximum amount of arena points the player can accrue (number)
GetMaxCombatRatingBonus
Returns the maximum possible percentage bonus for a given combat rating.
max = GetMaxCombatRatingBonus(ratingIndex)
While this function can be applied to all combat ratings, it is currently only
used in the default UI to account for the cap on (incoming) critical strike
damage and mana drains provided by Resilience ratingspecifically, in
generating the tooltip where Resilience rating is shown in the Character
window (PaperDollFrame).
Arguments:
ratingIndexWhich rating to query; the following global constants can be
used for standard values: (number)
CR_BLOCKBlock skill
Chapter 27 API Reference 739
CR_CRIT_MELEEMelee critical strike chance
CR_CRIT_RANGEDRanged critical strike chance
CR_CRIT_SPELLSpell critical strike chance
CR_CRIT_TAKEN_MELEEResilience (as applied to melee attacks)
CR_CRIT_TAKEN_RANGEDResilience (as applied to ranged attacks)
CR_CRIT_TAKEN_SPELLResilience (as applied to spell effects)
CR_DEFENSE_SKILLDefense skill
CR_DODGEDodge skill
CR_HASTE_MELEEMelee haste
CR_HASTE_RANGEDRanged haste
CR_HASTE_SPELLSpell haste
CR_HIT_MELEEMelee chance to hit
CR_HIT_RANGEDRanged chance to hit
CR_HIT_SPELLSpell chance to hit
CR_HIT_TAKEN_MELEE—Unused
CR_HIT_TAKEN_RANGED—Unused
CR_HIT_TAKEN_SPELL—Unused
CR_PARRYParry skill
CR_WEAPON_SKILLWeapon skill
CR_WEAPON_SKILL_MAINHANDMain-hand weapon skill
CR_WEAPON_SKILL_OFFHANDOffhand weapon skill
CR_WEAPON_SKILL_RANGEDRanged weapon skill
Returns:
maxThe maximum possible percentage bonus for the given rating (number)
GetMaxDailyQuests
Returns the maximum number of daily quests that can be completed each day.
max = GetMaxDailyQuests()
Returns:
maxThe maximum number of daily quests that can be completed each day
(number)
GetMerchantItemCostInfo
Returns information about alternate currencies required to purchase an item
from a vendor.
honorPoints, arenaPoints, itemCount = GetMerchantItemCostInfo(index)
Arguments:
indexIndex of an item in the vendor’s listing (between 1and
GetMerchantNumItems())(number)
Returns:
honorPointsAmount of honor points required to purchase the item (number)
arenaPointsAmount of arena points required to purchase the item (number)
740 Part IV Reference
itemCountNumber of different item currencies required to purchase the
item (see GetMerchantItemCostItem() for amount of each item currency
required) (number)
GetMerchantItemCostItem
Returns information about currency items required to purchase an item from a
vendor.
texture, value, link = GetMerchantItemCostItem(index, currency)
Arguments:
indexIndex of an item in the vendor’s listing (between 1and
GetMerchantNumItems())(number)
currencyIndex of one of the item currencies required to purchase the item
(between 1and select(3,GetMerchantItemCostInfo(index)))(number)
Returns:
texturePath to an icon texture for the currency item (string)
valueAmount of the currency required for purchase (number)
linkA hyperlink for the currency item (string, hyperlink)
GetMerchantItemInfo
Returns information about an item available for purchase from a vendor.
name, texture, price, quantity, numAvailable, isUsable, i
extendedCost = GetMerchantItemInfo(index)
Arguments:
indexIndex of an item in the vendor’s listing (between 1and
GetMerchantNumItems())(number)
Returns:
name—Name of the item (string)
texturePathtoanicontexturefortheitem(string)
priceCurrent cost to purchase the item from this vendor (in copper)
(number)
quantityNumber of stacked items per purchase (number)
numAvailableNumber of items available for purchase, if the vendor has a
limited stock of the item; -1if the vendor has an unlimited supply of the item
(number)
isUsable1if the player can use or equip the item; otherwise nil (1nil)
extendedCost1if the item’s price uses one or more alternate currencies
(for which details can be found via GetMerchantItemCostInfo(index));
otherwise nil (1nil)
GetMerchantItemLink
Returns a hyperlink for an item available for purchase from a vendor.
link = GetMerchantItemLink(index)
Arguments:
indexIndex of an item in the vendor’s listing (between 1and
GetMerchantNumItems())(number)
Chapter 27 API Reference 741
Returns:
linkA hyperlink for the item (string, hyperlink)
GetMerchantItemMaxStack
Returns the maximum number of an item allowed in a single purchase.
maxStack = GetMerchantItemMaxStack(index)
Determines the largest value usable for the second argument (quantity)of
BuyMerchantItem() when purchasing the item. For most items, this is the
same as the maximum stack size of the item. Returns 1 for items purchased in
bundles (e.g. food or drink in groups of 5, ammunition in groups of 200, etc), as
such items can only be purchased one bundle at a time.
Arguments:
indexIndex of an item in the vendor’s listing (between 1and
GetMerchantNumItems())(number)
Returns:
maxStackLargest number of items allowed in a single purchase (number)
Example:
-- Buys the largest quantity possible in one purchase for
-- the given index
BuyMerchantItem(index, GetMerchantItemMaxStack(index))
GetMerchantNumItems
Returns the number of different items available for purchase from a vendor.
numMerchantItems = GetMerchantNumItems()
Returns:
numMerchantItemsNumber of different items available for purchase
(number)
GetMinimapZoneText
Returns the name of the current area (as displayed in the Minimap).
zoneText = GetMinimapZoneText()
Matches GetSubZoneText(),GetRealZoneText() or GetZoneText().
Returns:
zoneTextName of the area containing the player’s current location (string)
GetMirrorTimerInfo
Returns information about special countdown timers.
timer, value, maxvalue, scale, paused, label = GetMirrorTimerInfo(index)
Arguments:
indexIndex of an available timer (between 1and MIRRORTIMER_NUMTIMERS)
(number)
Returns:
timerNon-localized token identifying the type of timer (string)
742 Part IV Reference
BREATHUsed for the Breath timer when swimming underwater
DEATHCurrently unused
EXHAUSTIONUsed for the Fatigue timer when swimming far from shore
FEIGNDEATHUsed for the Hunter Feign Death ability
valueNumber of seconds remaining before the timer expires (number)
maxvalueMaximum value of the timer (number)
scaleRateatwhichthetimerbarshouldmove(e.g.-1for a slowly ‘‘empty-
ing’’ bar, 10 for a quickly ‘‘filling’’ bar); unused in the default UI (number)
paused1if the timer is currently paused; otherwise 0 (number)
labelLocalized text to be displayed for the timer (string)
GetMirrorTimerProgress
Returns a high-resolution value for a special countdown timer.
progress = GetMirrorTimerProgress(“timer“)
Arguments:
timerNon-localized token identifying the type of timer (string)
BREATHUsed for the Breath timer when swimming underwater
DEATHCurrently unused
EXHAUSTIONUsed for the Fatigue timer when swimming far from shore
FEIGNDEATHUsed for the Hunter Feign Death ability
Returns:
progressNumber of milliseconds remaining before the timer expires
(number)
GetModifiedClick
Returns the keys/buttons bound for a modified click action.
binding = GetModifiedClick(“name“)
Arguments:
nameToken identifying a modified click action (string)
Returns:
bindingThe set of modifiers (and mouse button, if applicable) registered for
the action (string,binding)
GetModifiedClickAction
Returns the token identifying a modified click action.
action = GetModifiedClickAction(index)
Arguments:
indexIndex of a modified click action (between 1and GetNumModified
ClickActions())(number)
Returns:
actionToken identifying the modified click action, or nil if no action is
defined at the given index (string)
Chapter 27 API Reference 743
GetMoney
Returns the total amount of money currently in the player’s possession.
money = GetMoney()
Returns:
moneyAmount of money currently in the player’s possession (in copper)
(number)
Example:
local money = GetMoney()
local gold = floor(abs(money / 10000))
local silver = floor(abs(mod(money / 100, 100)))
local copper = floor(abs(mod(money, 100)))
print(format(“I have %d gold %d silver %d copper.“, gold, i
silver, copper))
GetMouseButtonClicked
Returns which mouse button triggered the current script.
button = GetMouseButtonClicked()
If called in a line of execution that started with a click handler
(OnMouseDown, OnMouseUp, OnClick, OnDoubleClick, PreClick, or
PostClick), returns a string identifying which mouse button triggered the
handler. Otherwise, returns nil.
Returns:
buttonName of the mouse button that triggered the current script (string)
GetMouseButtonName
Returns the name for a mouse button specified by number.
buttonName = GetMouseButtonName(buttonNumber)
Arguments:
buttonNumberA mouse button number (1-5) (number)
Returns:
buttonNameThe name of the given mouse button (string)
Button4
Button5
LeftButton
MiddleButton
RightButton
GetMouseFocus
Returns the frame that is currently under the mouse, and has mouse input
enabled.
frame = GetMouseFocus()
Returns:
frameThe frame that currently has the mouse focus (table)
Example:
-- Returns the name of the frame under the mouse, if it’s named
local frame = GetMouseFocus()
if not frame then
744 Part IV Reference
ChatFrame1:AddMessage(“There is no mouse enabled frame under i
the cursor“)
else
local name = frame:GetName() or tostring(frame)
ChatFrame1:AddMessage(name .. “ has the mouse focus“)
end
GetMovieResolution
Returns the horizontal resolution available for displaying movie content.
resolution = GetMovieResolution()
Returns:
resolutionHorizontal resolution (in pixels) available for displaying movie
content (number)
GetMultisampleFormats
Returns a list of available multisample settings.
color, depth, multisample, ... = GetMultisampleFormats()
Used in the default UI to provide descriptions of multisample settings
(e.g. ‘‘24-bit color 24-bit depth 6x multisample’’).
Indices used by GetCurrentMultisampleFormat() and
SetMultisampleFormat() refer to the groups of color,depth and
multisample values returned by this function; e.g. index 1 refers to values 1
through 3, index 2 to values 4 through 6, etc.
Returns:
colorColor depth (in bits) (number)
depthVideo depth (in bits) (number)
multisampleNumber of samples per pixel (number)
...Additional sets of color,depth and multisample values, one for each
multisample setting (list)
Example:
local index = GetCurrentMultisampleFormat()
local formatsIndex = (index - 1) * 3 + 1
local color, depth, samples = select(formatsIndex, i
GetMultisampleFormats())
print(format(“%d-bit color %d-bit depth %dx multisample“, color, i
depth, samples))
GetMuteName
Returns the name of a character on the mute list.
name = GetMuteName(index)
Arguments:
indexIndex of an entry in the mute listing (between 1and GetNumMutes())
(number)
Returns:
nameName of the muted character (string)
Chapter 27 API Reference 745
GetMuteStatus
Returns whether a character is muted or silenced.
muteStatus = GetMuteStatus(“unit“ [, “channel“]) or i
GetMuteStatus(“name“ [, “channel“])
If the channel argument is specified, this function checks the given character’s
voice/silence status on the channel as well as for whether the character is on
the player’s Muted list.
Arguments:
unit—A unit to query (string,unitID)
nameName of a character to query (string)
channel (optional)Name of a voice channel (string)
Returns:
muteStatus1if the character is muted; otherwise nil (1nil)
GetNetStats
Returns information about current network connection performance.
bandwidthIn, bandwidthOut, latency = GetNetStats()
Returns:
bandwidthInCurrent incoming bandwidth (download) usage, measured in
KB/s (number)
bandwidthOutCurrent outgoing bandwidth (upload) usage, measured in
KB/s (number)
latencyAverage roundtrip latency to the server (only updated every 30 sec-
onds) (number)
GetNewSocketInfo
Returns information about a gem added to a socket.
name, texture, matches = GetNewSocketInfo(index)
If the given socket contains a new gem (one that has been placed in the UI, but
not yet confirmed for permanently socketing into the item), returns
information for that gem. If the socket is empty or has a permanently socketed
gem but no new gem, returns nil.
Only returns valid information when the Item Socketing UI is open
(i.e. between the SOCKET_INFO_UPDATE and SOCKET_INFO_CLOSE events).
Arguments:
indexIndex of a gem socket (between 1and GetNumSockets())(number)
Returns:
nameName of the gem added to the socket (string)
texturePathtoanicontextureforthegemaddedtothesocket(string)
matches1if the gem matches the socket’s color; otherwise nil (1nil)
GetNewSocketLink
Returns a hyperlink for a gem added to a socket.
link = GetNewSocketLink(index)
746 Part IV Reference
If the given socket contains a new gem (one that has been placed in the UI, but
not yet confirmed for permanently socketing into the item), returns an item
link for that gem. If the socket is empty or has a permanently socketed gem but
no new gem, returns nil.
Only returns valid information when the Item Socketing UI is open
(i.e. between the SOCKET_INFO_UPDATE and SOCKET_INFO_CLOSE events).
Arguments:
indexIndex of a gem socket (between 1and GetNumSockets())(number)
Returns:
linkA hyperlink for the gem added to the socket (string, hyperlink)
GetNextAchievement
Returns the next achievement for an achievement which is part of a series.
nextID, completed = GetNextAchievement(id)
Arguments:
idThe numeric ID of an achievement (number)
Returns:
nextIDIf the given achievement is part of a series and not the last in its
series, the ID of the next achievement in the series; otherwise nil (number)
completedTrue if the next achievement has been completed; otherwise nil
(boolean)
GetNextStableSlotCost
Returns the cost of the next available stable slot.
money = GetNextStableSlotCost()
Returns 0 if all available slots have been purchased.
Returns:
moneyCost of the next available stable slot (in copper) (number)
GetNumActiveQuests
Returns the number of quests which can be turned in to the current Quest
NPC.
numActiveQuests = GetNumActiveQuests()
Only returns valid information after a QUEST_GREETING event.
Note: Most quest NPCs present active quests using the
GetGossipActiveQuests() instead of this function.
Returns:
numActiveQuestsNumber of quests which can be turned in to the current
Quest NPC (number)
GetNumAddOns
Returns the number of addons in the addon listing.
numAddons = GetNumAddOns()
Returns:
numAddonsThe number of addons in the addon listing (number)
Chapter 27 API Reference 747
GetNumArenaOpponents
Returns the number of enemy players in an arena match.
numOpponents = GetNumArenaOpponents()
Returns:
numOpponentsNumberofenemyplayersinanarenamatch(number)
GetNumArenaTeamMembers
Returns the number of members in an arena team.
numMembers = GetNumArenaTeamMembers(teamindex, showOffline)
Arguments:
teamindexThe index of the arena team, based on the order they are displayed
in the PvP tab. (number)
showOfflineTrue to include currently offline members in the count; other-
wise false (boolean)
Returns:
numMembersNumber of characters on the team (number)
GetNumAuctionItems
Returns the number of auction items in a listing.
numBatchAuctions, totalAuctions = GetNumAuctionItems(“list“)
Arguments:
listType of auction listing (string)
bidderAuctions the player has bid on
listAuctions the player can browse and bid on or buy out
ownerAuctions the player placed
Returns:
numBatchAuctionsNumber of auctions in the current page of the listing
(number)
totalAuctionsTotal number of auctions available for the listing (number)
GetNumAvailableQuests
Returns the number quests available from the current Quest NPC.
numAvailableQuests = GetNumAvailableQuests()
Only returns valid information after a QUEST_GREETING event.
Note: Most quest NPCs present available quests using the
GetGossipAvailableQuests() instead of this function.
Returns:
numAvailableQuestsNumber of quests available from the current Quest
NPC (number)
GetNumBankSlots
Returns information about purchased bank bag slots.
numSlots, isFull = GetNumBankSlots()
Returns:
numSlotsNumber of bank bag slots the player has purchased (number)
748 Part IV Reference
isFull1if the player has purchased all available slots; otherwise nil (1nil)
GetNumBattlefieldFlagPositions
Returns the number of battleground flags for which map position information
is available.
numFlags = GetNumBattlefieldFlagPositions()
Returns:
numFlagsNumber of battleground flags for which map position information
is available (number)
GetNumBattlefieldPositions
Returns the number of team members in the battleground not in the player’s
group.
numTeamMembers = GetNumBattlefieldPositions()
Still used in the default UI but no longer useful; always returns 0, as all team
members in a battleground match are automatically joined into a raid group.
Returns:
numTeamMembersNumber of team members in the battleground not in the
player’s party or raid (number)
GetNumBattlefieldScores
Returns the number of participant scores available in the current battleground.
numScores = GetNumBattlefieldScores()
Returns:
numScoresNumber of participant scores available in the current battle-
ground; 0 if not in a battleground (number)
GetNumBattlefieldStats
Returns the number of battleground-specific statistics on the current
battleground’s scoreboard.
numStats = GetNumBattlefieldStats()
Battleground-specific statistics include flags captured in Warsong Gulch,
towers assaulted in Alterac Valley, etc. For the name and icon associated with
each statistic, see GetBattlefieldStatInfo().
Returns:
numStatsNumber of battleground-specific scoreboard columns (number)
GetNumBattlefieldVehicles
Returns the number of special vehicles in the current zone.
numVehicles = GetNumBattlefieldVehicles()
Used only for certain vehicles in certain zones: includes the airships in
Icecrown as well as vehicles used in Ulduar, Wintergrasp, and Strand of the
Ancients.
Returns:
numVehiclesNumber of special vehicles (number)
Chapter 27 API Reference 749
GetNumBattlefields
Returns the number of instances available for a battleground.
numBattlefields = GetNumBattlefields([index])
Arguments:
index (optional)Index of a battleground (between 1and NUM_BATTLE
GROUNDS), if using the queue-anywhere UI; not used when choosing an instance
for a single battleground (e.g. at a battlemaster or battleground portal) (number)
Returns:
numBattlefieldsNumber of instances currently available for the battle-
ground (number)
GetNumBattlegroundTypes
Returns the number of different battlegrounds available.
numBattlegrounds = GetNumBattlegroundTypes()
Refers to distinct battlegrounds, not battleground instances. Does not indicate
the number of battlegrounds the player can enter: for that, see
GetBattlegroundInfo.
As of WoW 3.2, should always return 6 for Alterac Valley, Warsong Gulch,
Arathi Basin, Eye of the Storm, Strand of the Ancients, and Isle of Conquest. If
a future patch adds a new battleground, this function will reflect that.
Returns:
numBattlegroundsNumber of different battlegrounds available (number)
GetNumBindings
Returns the number of entries in the key bindings list.
numBindings = GetNumBindings()
Returns:
numBindingsNumber of binding actions (and headers) in the key bindings
list (number)
GetNumBuybackItems
Returns the number of items recently sold to a vendor and available to be
repurchased.
numBuybackItems = GetNumBuybackItems()
Returns:
numBuybackItemsNumber of items available to be repurchased (number)
GetNumChannelMembers
Returns the number of members in a chat channel.
numMembers = GetNumChannelMembers(id)
Arguments:
idNumeric identifier of a chat channel (number)
Returns:
numMembersNumber of characters in the channel (number)
750 Part IV Reference
GetNumCompanions
Returns the number of mounts or non-combat pets the player can summon.
count = GetNumCompanions(“type“)
Arguments:
type—The type of companion (string)
CRITTERNon-combat pets
MOUNT—Mounts
Returns:
countThe number of available companions (number)
GetNumComparisonCompletedAchievements
Returns the number of achievements earned by the comparison unit.
total, completed = GetNumComparisonCompletedAchievements()
Does not include Feats of Strength.
Returns:
totalTotal number of achievements currently in the game (number)
completedNumber of achievements earned by the comparison unit (number)
GetNumCompletedAchievements
Returns the number of achievements earned by the player.
total, completed = GetNumCompletedAchievements()
Does not include Feats of Strength.
Returns:
totalTotal number of achievements currently in the game (number)
completedNumber of achievements earned by the player (number)
GetNumDeclensionSets
Returns the number of suggested declension sets for a name.
numSets = GetNumDeclensionSets(“name“, gender)
Used in the Russian localized World of Warcraft client; see DeclineName for
further details. Returns 0 in other locales.
Arguments:
nameNominative form of the player’s or pet’s name (string)
genderGender for names (for declensions of the player’s name, should
match the player’s gender; for the pet’s name, should be neuter) (number)
1ornil—Neuter
2—Male
3—Female
Returns:
numSetsNumber of available declension sets usable with DeclineName
(number)
Chapter 27 API Reference 751
GetNumDisplayChannels
Returns the number of entries in the channel list display.
channelCount = GetNumDisplayChannels()
Returns:
channelCountNumber of channels and group headers to be displayed in the
channel list (number)
GetNumDungeonMapLevels
Returns the number of map images for the world map’s current zone.
numLevels = GetNumDungeonMapLevels()
Used in zones with more than one ‘‘floor’’ or area such as Dalaran and several
Wrath of the Lich King dungeons and raids.
Returns:
numLevelsNumber of map images (number)
GetNumEquipmentSets
Returns the number of saved equipment sets.
numSets = GetNumEquipmentSets()
Returns:
numSetsNumber of saved equipment sets (number)
GetNumFactions
Returns the number of entries in the reputation UI.
numFactions = GetNumFactions()
Entries in the reputation UI can be major group headers (Classic, Burning
Crusade, Wrath of the Lich King, Inactive, etc.), the sub-group headers within
them (Alliance Forces, Steamwheedle Cartel, Horde Expedition, Shattrath City,
etc.), or individual factions (Darkmoon Faire, Orgrimmar, Honor Hold, Kirin
Tor, etc.).
This function returns not the total number of factions (and headers) known,
but the number which should currently be visible in the UI according to the
expanded/collapsed state of headers.
Returns:
numFactionsThe number of visible factions and headers (number)
GetNumFrames
Returns the number of existing Frame objects (and derivatives).
numFrames = GetNumFrames()
Only counts Frame objects and derivatives thereof (e.g. Button, Minimap, and
StatusBar; but not FontString, AnimationGroup, and Texture).
Returns:
numFramesNumber of existing Frame objects (and derivatives) (number)
752 Part IV Reference
GetNumFriends
Returns the number of characters on the player’s friends list.
numFriends = GetNumFriends()
Returns:
numFriendsNumber of characters currently on the friends list (number)
GetNumGossipActiveQuests
Returns the number of quests which can be turned in to the current Gossip
NPC.
num = GetNumGossipActiveQuests()
These quests are displayed with a question mark icon in the default UI’s
GossipFrame.
Returns:
numNumber of quests which can be turned in to the current Gossip NPC
(number)
GetNumGossipAvailableQuests
Returns the number of quests available from the current Gossip NPC.
num = GetNumGossipAvailableQuests()
These quests are displayed with an exclamation mark icon in the default UI’s
GossipFrame.
Returns:
numNumber of quests available from the current Gossip NPC (number)
GetNumGossipOptions
Returns the number of non-quest dialog options for the current Gossip NPC.
numOptions = GetNumGossipOptions()
Used by the default UI to skip greeting gossip for NPCs which provide only a
greeting and one gossip option leading to the NPC’s main interaction type (e.g.
flight masters, merchants).
Returns:
numOptionsNumber of options available from the current Gossip NPC
(number)
GetNumGuildBankMoneyTransactions
Returns the number of transactions in the guild bank money log.
numTransactions = GetNumGuildBankMoneyTransactions()
Returns:
numTransactionsNumber of transactions in the money log (number)
GetNumGuildBankTabs
Returns the number of purchased tabs in the guild bank.
numTabs = GetNumGuildBankTabs()
Chapter 27 API Reference 753
Returns valid information even if the player is not interacting with a guild
bank vault.
Returns:
numTabsNumber of active tabs in the guild bank (number)
GetNumGuildBankTransactions
Returns the number of entries in a guild bank tab’s transaction log.
numTransactions = GetNumGuildBankTransactions(tab)
Only returns valid information following the GUILDBANKLOG_UPDATE event
which fires after calling QueryGuildBankLog().
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
Returns:
numTransactionsNumber of transactions in the tab’s log (number)
GetNumGuildEvents
Returns the number of entries in the guild event log.
numEvents = GetNumGuildEvents()
Only returns valid data after calling QueryGuildEventLog() and the
following GUILD_EVENT_LOG_UPDATE event has fired.
Returns:
numEventsNumber of entries in the guild event log (number)
GetNumGuildMembers
Returns the number of members in the guild roster.
numGuildMembers = GetNumGuildMembers([includeOffline])
Arguments:
includeOffline (optional)True to count all members in the guild; false
or omitted to count only those members currently online (boolean)
Returns:
numGuildMembersNumber of members in the guild roster (number)
GetNumIgnores
Returns the number of characters on the player’s ignore list.
numIgnores = GetNumIgnores()
Returns:
numIgnoresNumber of characters currently on the ignore list (number)
GetNumLFGResults
Returns the number of results from a LFM query.
numResults, totalCount = GetNumLFGResults(type, index)
Arguments:
typeIndex of an LFG query type (in the list returned by GetLFGTypes())
(number)
754 Part IV Reference
indexIndex of an LFG entry (in the list returned by GetLFGTypeEntries
(type))(number)
Returns:
numResultsNumber of results available for the specific query (number)
totalCountTotal number of results cached by the client (number)
GetNumLanguages
Returns the number of languages the player character can speak.
languages = GetNumLanguages()
Returns:
languagesNumber of in-game languages known to the player char-
acter (generally 2 for most races, 1for Orcs or Humans) (number)
GetNumLootItems
Returns the number of items available to be looted.
numItems = GetNumLootItems()
Returns:
numItemsNumber of the items available to be looted (number)
GetNumMacroIcons
Returns the number of available macro icons.
numMacroIcons = GetNumMacroIcons()
Returns:
numMacroIconsThe number of available macro icons (number)
GetNumMacroItemIcons
Returns the number of available item icons.
numIcons = GetNumMacroItemIcons()
Despite the ‘‘macro’’ in the title, this function is only used by the default UI for
providing tab icon options in the guild bank.
Returns:
numIconsNumber of available item icons (number)
GetNumMacros
Returns the number of macros the player has stored.
numAccountMacros, numCharacterMacros = GetNumMacros()
Returns:
numAccountMacrosNumber of account-wide macros (number)
numCharacterMacrosNumber of character-specific macros (number)
GetNumMapLandmarks
Returns the number of landmarks on the world map.
numLandmarks = GetNumMapLandmarks()
Possible landmarks include PvP objectives (both in battlegrounds and in world
PvP areas), town and city markers on continent maps, and special markers
Chapter 27 API Reference 755
such as those used during the Scourge Invasion world event. Some landmarks
(such as those for towns on a zone map) exist but are not visible in the
default UI.
Returns:
numLandmarksThe number of landmarks on the current world map (number)
GetNumMapOverlays
Returns the number of overlays for the current world map zone.
numOverlays = GetNumMapOverlays()
Map overlays correspond to areas which are ‘‘discovered’’ when entered by
the player, ‘‘filling in’’ the blank areas of the world map.
Returns:
numOverlaysNumber of overlays for the current world map zone (number)
GetNumModifiedClickActions
Returns the number of modified click actions registered.
num = GetNumModifiedClickActions()
May return an invalid result if called when no modified click actions have been
registered (i.e. early in the UI loading process).
Returns:
numNumber of modified click actions registered (number)
GetNumMutes
Returns the number of characters on the player’s mute list.
numMuted = GetNumMutes()
Returns:
numMutedThe number of characters on the player’s mute list (number)
GetNumPartyMembers
Returns the number of additional members in the player’s party.
numPartyMembers = GetNumPartyMembers()
Returns:
numPartyMembersNumber of additional members in the player’s
party (between 1and MAX_PARTY_MEMBERS, or 0 if the player is not in a
party) (number)
GetNumPetitionNames
Returns the number of people who have signed the open petition.
numNames = GetNumPetitionNames()
Returns:
numNamesNumber of characters that have signed the petition (number)
GetNumQuestChoices
Returns the number of available quest rewards from which the player must
choose one upon completing the quest presented by a questgiver.
numQuestChoices = GetNumQuestChoices()
756 Part IV Reference
Only valid during the accept/decline or completion stages of a quest dialog
(following the QUEST_DETAIL or QUEST_COMPLETE events); otherwise may
return 0 or a value from the most recently displayed quest.
Returns:
numQuestChoicesNumber of available quest rewards from which
the player must choose one upon completing the quest (number)
GetNumQuestItems
Returns the number of different items required to complete the quest presented
by a questgiver.
numRequiredItems = GetNumQuestItems()
Usable following the QUEST_PROGRESS event in which it is determined
whether the player can complete the quest.
Returns:
numRequiredItemsNumber of different items required to complete the quest
(number)
GetNumQuestLeaderBoards
Returns the number of quest objectives for a quest in the player’s quest log.
numObjectives = GetNumQuestLeaderBoards([questIndex])
Arguments:
questIndex (optional)Index of a quest in the quest log (between 1and
GetNumQuestLogEntries()); if omitted, defaults to the selected quest (number)
Returns:
numObjectivesNumber of trackable objectives for the quest (number)
GetNumQuestLogChoices
Returns the number of available item reward choices for the selected quest in
the quest log.
numChoices = GetNumQuestLogChoices()
This function refers to quest rewards for which the player is allowed to choose
one item from among several; for items always awarded upon quest
completion, see GetNumQuestLogRewards.
Returns:
numChoicesNumber of items among which a reward can be chosen for com-
pleting the quest (number)
GetNumQuestLogEntries
Returns the number of quests and headers in the quest log.
numEntries, numQuests = GetNumQuestLogEntries()
Returns:
numEntriesTotal number of entries (quests and headers) (number)
numQuestsNumber of quests only (number)
Chapter 27 API Reference 757
GetNumQuestLogRewards
Returns the number of item rewards for the selected quest in the quest log.
numRewards = GetNumQuestLogRewards()
This function refers to items always awarded upon quest completion; for quest
rewards for which the player is allowed to choose one item from among
several, see GetNumQuestLogChoices.
Returns:
numRewardsNumber of rewards for completing the quest (number)
GetNumQuestRewards
Returns the number of different items always awarded upon completing the
quest presented by a questgiver.
numQuestRewards = GetNumQuestRewards()
Only valid during the accept/decline or completion stages of a quest dialog
(following the QUEST_DETAIL or QUEST_COMPLETE events); otherwise may
return 0 or a value from the most recently displayed quest.
Returns:
numQuestRewardsNumber of different items always awarded upon complet-
ing the quest (number)
GetNumQuestWatches
Returns the number of quests included in the objectives tracker.
numWatches = GetNumQuestWatches()
Returns:
numWatchesNumber of quests from the quest log currently marked for watch-
ing (number)
GetNumRaidMembers
Returns the number of members in the player’s raid.
numRaidMembers = GetNumRaidMembers()
Returns:
numRaidMembersNumber of members in the raid (including the player)
(number)
GetNumRoutes
Returns the number of hops from the current location to another taxi node.
numHops = GetNumRoutes(index)
Only returns valid data while interacting with a flight master (i.e. between the
TAXIMAP_OPENED and TAXIMAP_CLOSED events).
Arguments:
indexIndex of a flight point (between 1and NumTaxiNodes())(number)
Returns:
numHopsNumber of hops from the current location to the given node
(number)
758 Part IV Reference
GetNumSavedInstances
Returns the number of instances to which the player is saved.
savedInstances = GetNumSavedInstances()
Returns:
savedInstancesNumber of instances to which the player is saved (number)
GetNumShapeshiftForms
Returns the number of abilities to be presented on the stance/shapeshift bar.
numForms = GetNumShapeshiftForms()
Returns:
numFormsNumber of abilities to be presented on the stance/shapeshift bar
(number)
GetNumSkillLines
Returns the number of entries in the Skills UI list.
numSkills = GetNumSkillLines()
Includes both character skills (including non-ranked skills such as talent
schools and armor proficiencies, as well as progressively learned skills such as
trade skills, weapon skills, and Defense skill) and skill group headers. Reflects
the current state of the list (i.e. returns a lower number if group headers are
collapsed.)
Returns:
numSkillsNumber of skills and headers to be displayed in the Skills UI
(number)
GetNumSockets
Returns the number of sockets on the item currently being socketed.
numSockets = GetNumSockets()
Only returns valid information when the Item Socketing UI is open
(i.e. between the SOCKET_INFO_UPDATE and SOCKET_INFO_CLOSE events).
Returns:
numSocketsNumber of sockets on the item (number)
GetNumSpellTabs
Returns the number of tabs in the player’s spellbook.
numTabs = GetNumSpellTabs()
Returns:
numTabsNumber of spellbook tabs (number)
Example:
-- Prints the names of all spell tabs to chat
for i = 1, GetNumSpellTabs() do
local name = GetSpellTabInfo(i);
print(name);
end
Chapter 27 API Reference 759
GetNumStablePets
Returns the number of stabled pets.
numPets = GetNumStablePets()
Returned value does not include the current pet.
Returns:
numPetsNumber of pets in the stables (number)
GetNumStableSlots
Returns the number of stable slots the player has purchased.
numSlots = GetNumStableSlots()
Returns:
numSlotsNumber of usable stable slots (number)
GetNumTalentGroups
Returns the number of talent specs a character can switch among.
numTalentGroups = GetNumTalentGroups(isInspect, isPet)
Arguments:
isInspecttrue to query talent info for the currently inspected unit, false to
query talent info for the player (boolean)
isPettrue to query talent info for the player’s pet, false to query talent info
for the player (boolean)
Returns:
numTalentGroupsNumber of talent groups the character has enabled
(number)
1—Default
2The character has purchased Dual Talent Specialization
GetNumTalentTabs
Returns the number of talent tabs for the player, pet, or inspect target.
numTabs = GetNumTalentTabs(inspect, pet)
Arguments:
inspecttrue to return information for the currently inspected
unit; false to return information for the player (boolean)
pettrue to return information for the player’s pet; false to return informa-
tion for the player (boolean)
Returns:
numTabsNumber of talent tabs (number)
GetNumTalents
Returns the number of options in a talent tab.
numTalents = GetNumTalents(tabIndex, inspect, pet)
Arguments:
tabIndexIndex of a talent tab (between 1and GetNumTalentTabs())
(number)
760 Part IV Reference
inspecttrue to return information for the currently inspected
unit; false to return information for the player (boolean)
pettrue to return information for the player’s pet; false to return informa-
tion for the player (boolean)
Returns:
numTalentsNumber of different talent options (number)
GetNumTitles
Returns the number of available player titles.
numTitles = GetNumTitles()
Includes all titles, not just those earned by the player
Returns:
numTitlesNumber of available player titles (number)
GetNumTrackedAchievements
Returns the number of achievements flagged for display in the objectives
tracker UI.
count = GetNumTrackedAchievements()
Returns:
countNumber of achievements flagged for tracking (number)
GetNumTrackingTypes
Returns the number of available minimap object/unit tracking abilities.
count = GetNumTrackingTypes()
Returns:
countNumber of available tracking types (number)
GetNumTradeSkills
Returns the number of entries in the trade skill listing.
numSkills = GetNumTradeSkills()
Entries include both group headers and individual trade skill recipes. Reflects
the list as it should currently be displayed, not necessarily the complete list. If
headers are collapsed or a filter is enabled, a smaller number will be returned.
Returns 0 if a trade skill is not ‘‘open’’.
Returns:
numSkillsNumber of headers and recipes to display in the trade skill list
(number)
GetNumTrainerServices
Returns the number of entries in the trainer service listing.
numServices = GetNumTrainerServices()
Entries include both group headers and individual trainer services (i.e. spells
or recipes to be purchased). Reflects the list as it should currently be displayed,
Chapter 27 API Reference 761
not necessarily the complete list. If headers are collapsed or a filter is enabled, a
smaller number will be returned.
Returns 0 if not interacting with a trainer.
Returns:
numServicesNumber of headers and services to display in the trainer service
listing (number)
GetNumVoiceSessionMembersBySessionID
Returns the number of members in a voice channel.
numMembers = GetNumVoiceSessionMembersBySessionID(sessionId)
Arguments:
sessionIdIndex of a voice session (between 1and GetNumVoice
Sessions())(number)
Returns:
numMembersNumber of members in the voice channel (number)
GetNumVoiceSessions
Returns the number of available voice channels.
count = GetNumVoiceSessions()
Returns 0 if voice chat is disabled.
Returns:
countNumber of available voice sessions (number)
GetNumWhoResults
Returns the number of results from a Who system query.
numResults, totalCount = GetNumWhoResults()
Returns:
numResultsNumber of results returned (number)
totalCountNumber of results to display (number)
GetNumWorldStateUI
Returns the number of world state UI elements.
numUI = GetNumWorldStateUI()
World State UI elements include PvP, instance, and quest objective information
(displayed at the top center of the screen in the default UI) as well as more
specific information for ‘‘control point’’ style PvP objectives. Examples: the
Horde/Alliance score in Arathi Basin, the tower status and capture progress
bars in Hellfire Peninsula, the progress text in the Black Morass and Violet
Hold instances, and the event status text for quests The Light of Dawn and The
Battle For The Undercity.
Returns:
numUIReturns the number of world state elements (number)
GetObjectiveText
Returns a summary of objectives for the quest offered by a questgiver.
questObjective = GetObjectiveText()
762 Part IV Reference
Only valid when the questgiver UI is showing the accept/decline stage of a
quest dialog (between the QUEST_COMPLETE and QUEST_FINISHED events);
otherwise may return the empty string or a value from the most recently
displayed quest.
Returns:
questObjectiveThe objective text for the currently displayed quest
(string)
GetOptOutOfLoot
Returns whether the player has opted out of loot rolls.
isOptOut = GetOptOutOfLoot()
When opting out, no prompt will be shown for loot which ordinarily would
prompt the player to roll (need/greed) or pass; the loot rolling process will
continue for other group members as if the player had chosen to pass on every
roll.
Returns:
isOptOut1if the player has opted out of loot rolls; otherwise nil (1nil)
GetOwnerAuctionItems
Requests data from the server for the list of auctions created by the player.
The AUCTION_OWNED_LIST_UPDATE event fires if new data is available; listing
information can then be retrieved using GetAuctionItemInfo() or other
Auction APIs.
GetPVPDesired
Returns whether the player has manually enabled PvP status.
isPVPDesired = GetPVPDesired()
Only indicates whether the player has manually and directly enabled his PvP
flag (e.g. by typing ‘‘/pvp’’ or using the default UI’s menu when right-clicking
the player portrait); returns 0 if the player only became PvP flagged by
attacking an enemy player, entering an enemy zone, etc.
Returns:
isPVPDesired1if the PVP flag was toggled on by the player manually; other-
wise 0 (number)
GetPVPLifetimeStats
Returns the player’s lifetime total of honorable kills and highest rank achieved.
hk, highestRank = GetPVPLifetimeStats()
Highest rank achieved applies only to the older PvP rewards system that was
abandoned with the WoW 2.0 patch, but is still accurate for players who
participated in it.
Returns:
hkNumber of honorable kills the player has scored (number)
highestRankHighest rank the player ever achieved in the pre-2.0 PvP
rewards system (number)
Chapter 27 API Reference 763
GetPVPRankInfo
Returns information about a given PvP rank index.
rankName, rankNumber = GetPVPRankInfo(index [, “unit“])
These ranks are no longer in use, as they were part of the older PvP rewards
system that was abandoned with the WoW 2.0 patch.
Arguments:
indexIndex of a rank (begins at 1, corresponding to a never-used ‘‘Pariah’’
rank; actual ranks start at 5) (number)
unit (optional)A unit to use as basis for the rank name (i.e. to return
Horde rank names for Horde units and Alliance rank names for Alliance
units); if omitted, uses the player’s faction (string,unitID)
Returns:
rankNameName of the rank (string)
rankNumberIndex of the rank relative to unranked status (positive values for
ranks earned through honorable kills, negative values for the unused dishonor-
able ranks) (number)
GetPVPSessionStats
Returns the number of kills and honor points scored by the player since
logging in.
honorKills, honorPoints = GetPVPSessionStats()
Returns:
honorKillsNumber of honorable kills scored (number)
honorPointsAmount of honor currency earned (number)
GetPVPTimer
Returns the amount of time until the player’s PVP flag expires.
timer = GetPVPTimer()
Returns 300000 or higher if the player’s PvP flag is manually enabled or if the
player is in a PvP or enemy zone.
Returns:
timerMilliseconds remaining until the player’s PvP flag expires (number)
GetPVPYesterdayStats
Returns the number of kills and honor points scored by the player on the
previous day.
honorKills, honorPoints = GetPVPYesterdayStats()
Returns:
honorKillsNumber of honorable kills scored (number)
honorPointsAmount of honor currency earned (number)
GetParryChance
Returns the player’s parry chance.
chance = GetParryChance()
764 Part IV Reference
Returns:
chanceThe player’s percentage chance to parry melee attacks (number)
GetPartyAssignment
Returns whether a party/raid member is assigned a specific group role.
isAssigned = GetPartyAssignment(“assignment“, “unit“) or i
GetPartyAssignment(“assignment“, “name“ [, exactMatch])
Arguments:
assignmentA group role assignment (string)
MAINASSISTReturn whether the unit is assigned the main assist role
MAINTANKReturn whether the unit is assigned the main tank role
unitA unit in the player’s party or raid (string,unitID)
nameName of a unit in the player’s party or raid (string)
exactMatch (optional)True to check only units whose name exactly
matches the name given; false to allow partial matches (boolean)
Returns:
isAssigned1if the unit is assigned the specified role; otherwise nil (1nil)
GetPartyLeaderIndex
Returns the index of the current party leader.
index = GetPartyLeaderIndex()
Returns 0 if the player is the party leader or if the player is not in a party.
Returns:
indexNumeric portion of the party unitID for the party leader (e.g. 3 =
party3)(number)
GetPartyMember
Returns whether a party member exists at a given index.
hasMember = GetPartyMember(index)
Arguments:
indexIndex of a party member (between 1and MAX_PARTY_MEMBERS),
or the numeric portion of a party unitID (e.g. 3 =party3)(number)
Returns:
hasMember1if the given index corresponds to a member in the player’s
party; otherwise nil (1nil)
GetPetActionCooldown
Returns cooldown information about a given pet action slot.
start, duration, enable = GetPetActionCooldown(index)
Arguments:
indexIndex of a pet action button (between 1and NUM_PET_ACTION_SLOTS)
(number)
Returns:
start—The value of GetTime() at the moment the cooldown began, or 0 if the
action is ready (number)
Chapter 27 API Reference 765
durationThe length of the cooldown, or 0 if the action is ready (number)
enable1if a Cooldown UI element should be used to display the cooldown,
otherwise 0. (Does not always correlate with whether the action is ready.)
(number)
GetPetActionInfo
Returns information about a pet action.
name, subtext, texture, isToken, isActive, autoCastAllowed, i
autoCastEnabled = GetPetActionInfo(index)
Arguments:
indexIndex of a pet action button (between 1and NUM_PET_ACTION_SLOTS)
(number)
Returns:
nameLocalized name of the action, or a token which can be used to get the
localized name of a standard action (string)
subtextSecondary text for the action (generally a spell rank; e.g. ‘‘Rank 8’’)
(string)
texturePath to an icon texture for the action, or a token which can
be used to get the texture path of a standard action (string)
isToken1if the returned name and texture are tokens for standard actions,
which should be used to look up actual values (e.g. PET_ACTION_ATTACK,
PET_ATTACK_TEXTURE); nil if name and texture can be displayed as-is (1nil)
isActive1if the action is currently active; otherwise nil. (Indicates which
state is chosen for the follow/stay and aggressive/defensive/passive switches.)
(1nil)
autoCastAllowed1if automatic casting is allowed for the action; otherwise
nil (1nil)
autoCastEnabled1if automatic casting is currently turned on for the action;
otherwise nil (1nil)
GetPetActionSlotUsable
Returns whether a pet action can be used.
usable = GetPetActionSlotUsable(index)
Used in the default UI to show pet actions as grayed out when the pet cannot
be commanded to perform them (e.g. when the player or pet is stunned).
Arguments:
indexIndex of a pet action button (between 1and NUM_PET_ACTION_SLOTS)
(number)
Returns:
usable1if the pet action is currently available; otherwise nil (1nil)
GetPetActionsUsable
Returns whether the pet’s actions are usable.
petActionsUsable = GetPetActionsUsable()
766 Part IV Reference
Note: GetPetActionSlotUsable can return nil for individual actions even if
GetPetActionsUsable returns 1 (though not the other way around).
Returns:
petActionsUsable1if the pet’s actions are usable; otherwise nil (1nil)
GetPetExperience
Returns information about experience points for the player’s pet.
currXP, nextXP = GetPetExperience()
Returns:
currXPThe pet’s current amount of experience points (number)
nextXPTotal amount of experience points required for the pet to gain a level
(number)
GetPetFoodTypes
Returns a list of the food types the player’s pet will eat.
... = GetPetFoodTypes()
Returns:
...A list of strings, each the localized name of a food type the pet will eat
(list)
BreadBaked goods
CheeseCheese products
FishRaw and cooked fish
Fruit—Fruits
FungusMushrooms, lichens, and similar
MeatRaw and cooked meat
GetPetHappiness
Returns information about the player’s pet’s happiness.
happiness, damagePercentage = GetPetHappiness()
Returns:
happinessNumber identifying the pet’s current happiness level (number)
1Unhappy
2—Content
3Happy
damagePercentagePercentage multiplier for the pet’s outgoing damage
(number)
GetPetIcon
Returns an icon representing the current pet.
texture = GetPetIcon()
Used in the default Pet Stables and Talent UIs for hunter pets; returns nil for
other pets.
Returns:
texturePathtoanicontextureforthepet(string)
Chapter 27 API Reference 767
GetPetTalentTree
Returns the name of the talent tree used by the player’s current pet.
talent = GetPetTalentTree()
Hunter pets use one of three different talent trees according to pet type.
Returns nil if the player does not have a pet or the player’s current pet does
not use talents (i.e. warlock pets, quest pets, etc.)
Returns:
talentLocalized name of the pet’s talent tree (string)
GetPetTimeRemaining
Returns the time remaining before a temporary pet is automatically dismissed.
petTimeRemaining = GetPetTimeRemaining()
Temporary pets include priests’ Shadowfriend, mages’ Water Elemental, and
various quest-related pets.
Returns:
petTimeRemainingAmount of time remaining until the temporary pet is
automatically dismissed (in seconds), or nil if the player does not have a tempo-
rary pet (number)
GetPetitionInfo
Returns information about the currently open petition.
petitionType, title, bodyText, maxSignatures, originatorName, i
isOriginator, minSignatures = GetPetitionInfo()
Returns:
petitionTypeType of the petition (string)
arenaAn arena team charter
guildA guild charter
titleTitle of the petition (string)
bodyTextBody text of the petition (string)
maxSignaturesMaximum number of signatures allowed (number)
originatorNameName of the character who initially purchased the charter
(string)
isOriginator1if the player is the petition’s originator; otherwise nil (1nil)
minSignaturesMinimum number of signatures required to establish the
charter (number)
GetPetitionItemInfo
Returns information about a purchasable arena team charter.
name, texture, price = GetPetitionItemInfo(team)
Arguments:
teamIndex of a team size for a charter (number,arenaTeamID)
768 Part IV Reference
Returns:
nameName of the petition (string)
texturePath to an icon texture for the petition (string)
priceCost to purchase the petition (in copper) (number)
GetPetitionNameInfo
Returns the name of a character who has signed the currently offered petition.
name = GetPetitionNameInfo(index)
Arguments:
indexIndex of a signature slot on the petition (between 1and
minSignatures,whereminSignatures = select(7,GetPetitionInfo()))
(number)
Returns:
nameName of the signatory character, or nil if the slot has not yet been signed
(string)
GetPlayerFacing
Returns the player’s orientation (heading).
facing = GetPlayerFacing()
Indicates the direction the player model is (normally) facing and in which the
player will move if he begins walking forward, not the camera orientation.
Returns:
facingDirection the player is facing (in radians, 0 =north, values increasing
counterclockwise) (number)
GetPlayerInfoByGUID
Returns information about a player character identified by globally unique
identifier.
class, classFilename, race, raceFilename, sex = i
GetPlayerInfoByGUID(“guid“)
Returns nil if given the GUID of a non-player unit.
Arguments:
guidGlobally unique identifier of a player unit (string,guid)
Returns:
classLocalized name of the unit’s class (string)
classFilenameNon-localized token identifying the unit’s class (string)
raceLocalized name of the unit’s race (string)
raceFilenameNon-localized token identifying the unit’s race (string)
sexNumber identifying the unit’s gender (number)
1—Neuter / Unknown
2—Male
3—Female
Chapter 27 API Reference 769
GetPlayerMapPosition
Returns the position of the player’s corpse on the world map.
unitX, unitY = GetPlayerMapPosition(“unit“)
Returns 0,0 if the unit’s location is not visible on the current world map.
Arguments:
unitA unit in the player’s party or raid (string,unitID)
Returns:
unitXHorizontal position of the unit relative to the zone map (0 =left edge,
1=right edge) (number)
unitYVertical position of the unit relative to the zone map (0 =top, 1=bot-
tom) (number)
GetPlayerTradeMoney
Returns the amount of money offered for trade by the player.
amount = GetPlayerTradeMoney()
Returns:
amountAmount of money offered for trade by the player (in copper) (number)
GetPossessInfo
Returns information about special actions available while the player possesses
another unit.
texture, name = GetPossessInfo(index)
Used in the default UI to show additional special actions (e.g. canceling
possession) while the player possesses another unit through an ability such as
Eyes of the Beast or Mind Control.
Does not apply to actions (spells) belonging to the possessed unit; those are
regular actions (see GetActionInfo())whoseactionIDsbeginat
((NUM_ACTIONBAR_PAGES - 1 + GetBonusBarOffset()) *
NUM_ACTIONBAR_BUTTONS + 1).
Arguments:
indexIndex of a possession bar action (between 1and NUM_POSSESS_SLOTS)
(number)
Returns:
texturePathtoanicontexturefortheaction(string)
nameThe name of the spell in the queried possess bar slot. (string)
GetPowerRegen
Returns information about the player’s mana/energy/etc regeneration rate.
inactiveRegen, activeRegen = GetPowerRegen()
Contexts for inactiveRegen and activeRegen vary by power type.
If the player (currently) uses mana, activeRegen refers to mana regeneration
while casting (within five seconds of casting a spell) and inactiveRegen
refers to mana regeneration while not casting (more than five seconds after
770 Part IV Reference
casting a spell). For other power types, activeRegen refers to regeneration
while in combat and inactiveRegen to regeneration outside of combat.
Note that values returned can be negative: e.g. for rage and runic power users,
inactiveRegen describes the rate of power decay while not in combat.
Returns:
inactiveRegenPower change per second while inactive (number)
activeRegenPower change per second while active (number)
GetPreviousAchievement
Returns the previous achievement for an achievement which is part of a series.
previousID = GetPreviousAchievement(id)
Arguments:
idThe numeric ID of an achievement (number)
Returns:
previousIDIf the given achievement is part of a series and not the first in its
series, the ID of the previous achievement in the series; otherwise nil (number)
GetPreviousArenaSeason
Returns a number identifying the previous arena season.
season = GetPreviousArenaSeason()
New arena seasons begin every few months, resetting team rankings and
providing new rewards.
Returns:
seasonNumber identifying the previous arena season (number)
GetProgressText
Returns the quest progress text presented by a questgiver.
text = GetProgressText()
Only valid when the questgiver UI is showing the progress stage of a quest
dialog (between the QUEST_PROGRESS and QUEST_FINISHED events);
otherwise may return the empty string or a value from the most recently
displayed quest.
Returns:
textProgress text for the quest (string)
GetQuestBackgroundMaterial
Returns background display style information for a questgiver dialog.
material = GetQuestBackgroundMaterial()
The value returned can be used to look up background textures and text colors
for display:
Background textures displayed in the default UI can be found by
prepending “Interface\\ItemTextFrame\\ItemText-“ and appending
“-TopLeft“,-TopRight“,“-BotLeft“,“-BotRight“ to the material
string (e.g. “Interface\\ItemTextFrame\\ItemText-Stone-TopLeft“).
Chapter 27 API Reference 771
Colors for body and title text can be found by calling GetMaterialText
Colors(material) (a Lua function implemented in the Blizzard UI).
In cases where this function returns nil, the default UI uses the colors and
textures for ‘‘Parchment’’.
Returns:
materialString identifying a display style for the questgiver dialog, or nil
for the default style (string)
BronzeColored metallic background
MarbleLight stone background
ParchmentYellowed parchment background (default)
SilverGray metallic background
StoneDark stone background
Blizzard UI GetQuestDifficultyColor
Returns a table of color values indicating the difficulty of a quest’s level as
compared to the player’s.
color = GetQuestDifficultyColor(level)
Arguments:
levelLevel for which to compare difficulty (number)
Returns:
colorA table containing color values (keyed r,g,andb) representing the
difficulty of a quest at the input level as compared to the player’s (table)
GetQuestGreenRange
Returns the level range in which a quest below the player’s level still
rewards XP.
range = GetQuestGreenRange()
If a quest’s level is up to range levels below the player’s level, the quest is
considered easy but still rewards experience points upon completion; these
quests are colored green in the default UI’s quest log. (Quests more than range
levels below the player’s are colored gray in the default UI and reward
no XP.)
Returns:
rangeMaximum difference between player level and a lower quest level for a
quest to reward experience (number)
Example:
-- function used to color quest log entries in the default UI
function GetDifficultyColor(level)
local levelDiff = level - UnitLevel(“player“);
local color
if ( levelDiff >= 5 ) then
color = QuestDifficultyColor[“impossible“];
elseif ( levelDiff >= 3 ) then
color = QuestDifficultyColor[“verydifficult“];
772 Part IV Reference
elseif ( levelDiff >= -2 ) then
color = QuestDifficultyColor[“difficult“];
elseif ( -levelDiff <= GetQuestGreenRange() ) then
color = QuestDifficultyColor[“standard“];
else
color = QuestDifficultyColor[“trivial“];
end
return color;
end
GetQuestIndexForTimer
Returns the quest log index of a timed quest’s timer.
questIndex = GetQuestIndexForTimer(index)
Arguments:
indexIndex of a timer (in the list returned by GetQuestTimers())
(number)
Returns:
questIndexIndex of the quest in the quest log (between 1and
GetNumQuestLogEntries())(number)
GetQuestIndexForWatch
Returns the quest log index of a quest in the objectives tracker.
questIndex = GetQuestIndexForWatch(index)
Arguments:
indexIndex of a quest in the list of quests on the objectives tracker (between 1
and GetNumQuestWatches())(number)
Returns:
questIndexIndex of the quest in the quest log (between 1and
GetNumQuestLogEntries())(number)
GetQuestItemInfo
Returns information about items in a questgiver dialog.
name, texture, numItems, quality, isUsable = i
GetQuestItemInfo(“type“, index)
Only valid when the questgiver UI is showing the accept/decline, progress, or
completion stages of a quest dialog (between the QUEST_DETAIL and
QUEST_FINISHED,QUEST_PROGRESS and QUEST_FINISHED,or
QUEST_COMPLETE and QUEST_FINISHED events); otherwise may return empty
values or those from the most recently displayed quest.
Arguments:
typeWhich of the possible sets of items to query (string)
choiceItems from which the player may choose a reward
requiredItems required to complete the quest
rewardItems given as reward for the quest
Chapter 27 API Reference 773
indexWhich item to query (from 1to GetNumQuestChoices(), GetNum
QuestItems(), or GetNumQuestRewards(), depending on the value of the
itemType argument) (number)
Returns:
nameThe name of the item (string)
texturePath to a texture for the item’s icon (string)
numItemsNumber of the item required or rewarded (number)
qualityThe quality of the item (number)
0Poor
1Common
2Uncommon
3—Rare
4—Epic
5Legendary
6—Artifact
isUsable1if the player can currently use/equip the item; otherwise nil
(1nil)
GetQuestItemLink
Returns a hyperlink for an item in a questgiver dialog.
link = GetQuestItemLink(“itemType“, index)
Only valid when the questgiver UI is showing the accept/decline, progress, or
completion stages of a quest dialog (between the QUEST_DETAIL and
QUEST_FINISHED,QUEST_PROGRESS and QUEST_FINISHED,or
QUEST_COMPLETE and QUEST_FINISHED events); otherwise may return nil or
a value from the most recently displayed quest.
Arguments:
itemTypeToken identifying one of the possible sets of items (string)
choiceItems from which the player may choose a reward
requiredItems required to complete the quest
rewardItems given as reward for the quest
indexIndex of an item in the set (between 1and GetNumQuestChoices(),
GetNumQuestItems(),orGetNumQuestRewards(), according to itemType)
(number)
Returns:
linkA hyperlink for the item (string)
GetQuestLink
Returns a hyperlink for an entry in the player’s quest log.
link = GetQuestLink(questIndex)
Arguments:
questIndexIndex of a quest in the quest log (between 1and
GetNumQuestLogEntries())(number)
Returns:
linkA hyperlink for the quest (string, hyperlink)
774 Part IV Reference
GetQuestLogChoiceInfo
Returns information about available item rewards for the selected quest in the
quest log.
name, texture, numItems, quality, isUsable = i
GetQuestLogChoiceInfo(index)
This function refers to quest rewards for which the player is allowed to choose
one item from among several; for items always awarded upon quest
completion, see GetQuestLogRewardInfo.
Arguments:
indexIndex of a quest reward choice (between 1and GetNumQuestLog-
Choices()) (number)
Returns:
name—Name of the item (string)
texturePathtoanicontexturefortheitem(string)
numItemsNumber of items in the stack (number)
qualityQuality of the item (number, itemQuality)
isUsable1if the player can use or equip the item; otherwise nil (1nil)
GetQuestLogGroupNum
Returns the suggested group size for the selected quest in the quest log.
suggestedGroup = GetQuestLogGroupNum()
Returns:
suggestedGroupRecommended number of players in a group attempting the
quest (number)
GetQuestLogItemLink
Returns a hyperlink for an item related to the selected quest in the quest log.
GetQuestLogItemLink(“itemType“, index)
Arguments:
itemTypeToken identifying one of the possible sets of items (string)
choiceItems from which the player may choose a reward
rewardItems always given as reward for the quest
indexIndex of an item in the set (between 1and GetNumQuestLogChoices()
or GetNumQuestLogRewards(), according to itemType)(number)
GetQuestLogLeaderBoard
Returns information about objectives for a quest in the quest log.
text, type, finished = GetQuestLogLeaderBoard(objective [, questIndex])
Arguments:
objectiveIndex of a quest objective (between 1and GetNumQuestLeader
Boards())(number)
questIndex (optional)Index of a quest in the quest log (between 1and
GetNumQuestLogEntries()); if omitted, defaults to the selected quest (number)
Chapter 27 API Reference 775
Returns:
textText of the objective (e.g. ‘‘Gingerbread Cookie: 0/5’’) (string)
typeType of objective (string)
eventRequires completion of a scripted event
itemRequires collecting a number of items
monsterRequires slaying a number of NPCs
objectRequires interacting with a world object
reputationRequires attaining a certain level of reputation with a faction
finished1if the objective is complete; otherwise nil (1nil)
GetQuestLogPushable
Return whether the selected quest in the quest log can be shared to party
members.
shareable = GetQuestLogPushable()
Returns:
shareable1if the quest is shareable; otherwise nil (1nil)
GetQuestLogQuestText
Returns the description and objective text for the selected quest in the quest
log.
questDescription, questObjectives = GetQuestLogQuestText()
Returns:
questDescriptionFull description of the quest (as seen in the NPC dialog
when accepting the quest) (string)
questObjectivesA (generally) brief summary of quest objectives (string)
GetQuestLogRequiredMoney
Returns the amount of money required for the selected quest in the quest log.
money = GetQuestLogRequiredMoney()
Returns:
moneyThe amount of money required to complete the quest (in copper)
(number)
GetQuestLogRewardHonor
Returns the honor reward for the selected quest in the quest log.
honor = GetQuestLogRewardHonor()
Returns:
honorThe amount of honor points rewarded for completing the quest
(number)
GetQuestLogRewardInfo
Returns information about item rewards for the selected quest in the quest log.
name, texture, numItems, quality, isUsable = i
GetQuestLogRewardInfo(index)
776 Part IV Reference
This function refers to items always awarded upon quest completion; for quest
rewards for which the player is allowed to choose one item from among
several, see GetQuestLogChoiceInfo.
Arguments:
indexIndex of a quest reward (between 1and GetNumQuestLogRewards())
(number)
Returns:
name—Name of the item (string)
texturePathtoanicontexturefortheitem(string)
numItemsNumber of items in the stack (number)
qualityQuality of the item (number, itemQuality)
isUsable1if the player can use or equip the item; otherwise nil (1nil)
GetQuestLogRewardMoney
Returns the money reward for the selected quest in the quest log.
money = GetQuestLogRewardMoney()
Returns:
moneyAmount of money rewarded for completing the quest (in copper)
(number)
GetQuestLogRewardSpell
Returns information about the spell reward for the selected quest in the quest
log.
texture, name, isTradeskillSpell, isSpellLearned = i
GetQuestLogRewardSpell()
If both isTradeskillSpell and isSpellLearned are nil, the reward is a
spell cast upon the player.
Returns:
texturePath to the spell’s icon texture (string)
nameName of the spell (string)
isTradeskillSpell1if the spell is a tradeskill recipe; otherwise nil (1nil)
isSpellLearned1if the reward teaches the player a new spell; otherwise nil
(1nil)
GetQuestLogRewardTalents
Returns the talent point reward for the selected quest in the quest log.
talents = GetQuestLogRewardTalents()
Returns 0for quests which do not award talent points.
(Very few quests award talent points; currently this functionality is only used
within the Death Knight starting experience.)
Returns:
talentsNumber of talent points to be awarded upon completing the quest
(number)
Chapter 27 API Reference 777
GetQuestLogRewardTitle
Returns the title reward for the selected quest in the quest log.
title = GetQuestLogRewardTitle()
Returns nil if no title is awarded or if no quest is selected.
Returns:
titleTitle to be awarded to the player upon completing the quest (string)
GetQuestLogSelection
Returns the index of the selected quest in the quest log.
questIndex = GetQuestLogSelection()
Returns:
questIndexIndex of the selected quest in the quest log (between 1and
GetNumQuestLogEntries())(number)
Example:
-- Prints information about the currently selected quest
local index = GetQuestLogSelection()
local name = GetQuestLogTitle(index)
if name then
print(“Currently viewing “ .. name)
end
GetQuestLogSpecialItemCooldown
Returns cooldown information about an item associated with a current quest.
start, duration, enable = GetQuestLogSpecialItemCooldown(questIndex)
Available for a number of quests which involve using an item (i.e. ‘‘Use the
MacGuffin to summon and defeat the boss’’, ‘‘Use this saw to fell 12 trees’’,
etc.)
Arguments:
questIndexIndex of a quest log entry with an associated usable
item (between 1and GetNumQuestLogEntries())(number)
Returns:
start—The value of GetTime() at the moment the cooldown began, or 0 if the
item is ready (number)
durationThe length of the cooldown, or 0 if the item is ready (number)
enable1if a Cooldown UI element should be used to display the cooldown,
otherwise 0. (Does not always correlate with whether the item is ready.)
(number)
GetQuestLogSpecialItemInfo
Returns information about a usable item associated with a current quest.
link, icon, charges = GetQuestLogSpecialItemInfo(questIndex)
Available for a number of quests which involve using an item (i.e. ‘‘Use the
MacGuffin to summon and defeat the boss’’, ‘‘Use this saw to fell
12 trees’’, etc.)
778 Part IV Reference
Arguments:
questIndexIndex of a quest log entry with an associated usable
item (between 1and GetNumQuestLogEntries())(number)
Returns:
linkA hyperlink for the item (string, hyperlink)
iconPathtoanicontexturefortheitem(string)
chargesNumber of times the item can be used, or 0 if no limit (number)
GetQuestLogSpellLink
Returns a hyperlink for a spell in the selected quest in the quest log.
link = GetQuestLogSpellLink()
Returns:
linkA hyperlink for the spell or tradeskill recipe (string, hyperlink)
GetQuestLogTimeLeft
Returns time remaining for the selected quest in the quest log.
questTimer = GetQuestLogTimeLeft()
If the selected quest is not timed, returns nil.
Returns:
questTimerThe amount of time left to complete the quest (number)
GetQuestLogTitle
Returns information about an entry in the player’s quest log.
questLogTitleText, level, questTag, suggestedGroup, isHeader, i
isCollapsed, isComplete, isDaily, questID = GetQuestLogTitle(questIndex)
Arguments:
questIndexIndex of a quest in the quest log (between 1and
GetNumQuestLogEntries())(number)
Returns:
questLogTitleTextTitle of the quest (string)
levelRecommended character level for attempting the quest (number)
questTagLocalized tag describing the type of quest (string)
DungeonDungeon or instance quest
EliteElite quest
Group—Group quest
Heroic—Heroic quest
PVPPVP specific quest
RaidRaid quest
nilStandard quest
suggestedGroupFor some group quests, the recommended
number of group members for attempting the quest (number)
isHeader1if the entry is a group header; nil if the entry is a quest (1nil)
isCollapsed1if the entry is a collapsed header; otherwise nil (1nil)
isCompleteWhether the quest is complete (number)
-1The quest was failed
Chapter 27 API Reference 779
1—The quest was completed
nilThequesthasyettoreachaconclusion
isDaily1if the quest is a daily quest; otherwise nil (1nil)
questID—The quests questID. (number)
GetQuestMoneyToGet
Returns the amount of money required to complete the quest presented by a
questgiver.
money = GetQuestMoneyToGet()
Usable following the QUEST_PROGRESS event in which it is determined
whether the player can complete the quest.
Returns:
moneyAmount of money required to complete the quest (in copper) (number)
GetQuestResetTime
Returns the amount of time remaining until the daily quest period resets.
time = GetQuestResetTime()
Returns:
timeAmount of time remaining until the daily quest period resets (in seconds)
(number)
Example:
-- Print the amount of time until dailies reset
print(“Daily quests reset in “ .. SecondsToTime(GetQuestResetTime()))
GetQuestReward
Finishes turning in a quest to a questgiver, selecting an item reward if
applicable.
GetQuestReward(choice)
Usable following the QUEST_COMPLETE event in which the questgiver presents
the player with rewards.
Arguments:
choiceIndex of a quest reward choice (between 1and GetNumQuest
Choices()), or nil if the quest does not offer a choice of item rewards (number)
GetQuestSpellLink
Returns a hyperlink for a spell in a questgiver dialog.
link = GetQuestSpellLink()
Only valid when the questgiver UI is showing the accept/decline, progress, or
completion stages of a quest dialog (between the QUEST_DETAIL and
QUEST_FINISHED,QUEST_PROGRESS and QUEST_FINISHED,or
QUEST_COMPLETE and QUEST_FINISHED events); otherwise may return empty
values or those from the most recently displayed quest.
780 Part IV Reference
Returns:
linkA hyperlink for the spell or tradeskill recipe (string, hyperlink)
GetQuestText
Returns the text for the quest offered by a questgiver.
text = GetQuestText()
Only valid when the questgiver UI is showing the accept/decline stage of a
quest dialog (between the QUEST_COMPLETE and QUEST_FINISHED events);
otherwise may return the empty string or a value from the most recently
displayed quest.
Returns:
textThe text for the currently displayed quest (string)
GetQuestTimers
Returns a list of the times remaining for any active timed quests.
... = GetQuestTimers()
Returns:
...A list of numbers, each the amount of time (in seconds) remaining for a
timed quest (number)
GetRaidRosterInfo
Returns information about a member of the player’s raid.
name, rank, subgroup, level, class, fileName, zone, online, isDead, i
role, isML = GetRaidRosterInfo(index)
Arguments:
indexIndex of the raid member (between 1and GetNumRaidMembers());
matches the numeric part of the unit’s raid unitID,e.g.21 for raid21
(number)
Returns:
nameName of the raid member (string)
rankRank of the member in the raid (number)
0—Raid member
1Raid Assistant
2—Raid Leader
subgroupIndex of the raid subgroup to which the member belongs (between
1and MAX_RAID_GROUPS)(number)
levelCharacter level of the member (number)
classLocalized name of the member’s class (string)
fileNameA non-localized token representing the member’s class (string)
zoneName of the zone in which the member is currently located (string)
online1if the member is currently online; otherwise nil (1nil)
isDead1if the member is currently dead; otherwise nil (1nil)
roleGroup role assigned to the member (string)
Chapter 27 API Reference 781
MAINASSIST
MAINTANK
isML1if the member is the master looter; otherwise nil (1nil)
GetRaidRosterSelection
Returns the index of the selected unit in the raid roster.
raidIndex = GetRaidRosterSelection()
Selection in the raid roster is used only for display in the default UI and has no
effect on other Raid APIs.
Returns:
raidIndexIndex of the raid member (between 1and GetNumRaid
Members()); matches the numeric part of the unit’s raid unitID,e.g.21 for
raid21 (number)
GetRaidTargetIndex
Returns the index of the raid target marker on a unit.
index = GetRaidTargetIndex(“unit“) or GetRaidTargetIndex(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
indexIndex of a target marker (number)
1—Star
2—Circle
3—Diamond
4—Triangle
5Moon
6—Square
7—Cross
8—Skull
nil—No marker
GetRangedCritChance
Returns the player’s ranged critical strike chance.
critChance = GetRangedCritChance()
Returns:
critChanceThe player’s percentage critical strike chance for ranged attacks
(number)
GetReadyCheckStatus
Returns a unit’s status during a ready check.
status = GetReadyCheckStatus(“unit“)
Returns nil for all units unless the player is the party/raid leader or a raid
assistant.
Arguments:
unitA unit in the player’s party or raid (string,unitID)
Returns:
statusReady check status for the unit (string)
782 Part IV Reference
“notready“Unit has responded as not ready
“ready“Unit has responded as ready
“waiting“Unit has not yet responded
nilNo ready check is in progress
GetReadyCheckTimeLeft
Returns the amount of time left on the current ready check.
timeLeft = GetReadyCheckTimeLeft()
Returns 0if no ready check is in progress.
Returns:
timeLeftAmount of time remaining on the ready check (in seconds)
(number)
GetRealNumPartyMembers
Returns the number of members in the player’s non-battleground party.
numMembers = GetRealNumPartyMembers()
When the player is in a party/raid and joins a battleground or arena, the
normal party/raid functions refer to the battleground’s party/raid, but the
game still keeps track of the player’s place in a non-battleground party/raid.
Returns:
numMembersNumber of members in the player’s non-battleground party
(number)
GetRealNumRaidMembers
Returns the number of members in the player’s non-battleground raid.
numMembers = GetRealNumRaidMembers()
When the player is in a party/raid and joins a battleground or arena, the
normal party/raid functions refer to the battleground’s party/raid, but the
game still keeps track of the player’s place in a non-battleground party/raid.
Returns:
numMembersNumber of members in the player’s non-battleground raid
(number)
GetRealZoneText
Returns the ‘‘official’’ name of the zone or instance in which the player is
located.
zoneName = GetRealZoneText()
This name matches that seen in the Who, Guild, and Friends UIs when
reporting character locations. It may differ from those the default UI displays
in other locations (GetZoneText() and GetMinimapZoneText()), especially
if the player is in an instance: e.g. this function returns ‘‘The Stockade’’ when
the others return ‘‘Stormwind Stockade’’.
Returns:
zoneNameName of the zone or instance (string)
Chapter 27 API Reference 783
GetRealmName
Returns the name of the player’s realm (server name).
realm = GetRealmName()
Returns:
realmThe name of the player’s realm (server) (string)
GetRefreshRates
Returns a list of available screen refresh rates.
... = GetRefreshRates()
The current refresh rate can be found in the gxRefresh CVar.
Returns:
...A list of numbers, each an available screen refresh rate (in hertz, or cycles
per second) (number)
GetReleaseTimeRemaining
Returns the amount of time remaining until the player’s spirit is automatically
released when dead.
timeleft = GetReleaseTimeRemaining()
Returns -1 if the player died in a dungeon or raid instance; in such cases, the
player’s spirit will not be released automatically (see RepopMe() to release
manually).
Returns:
timeleftAmount of time remaining until the player’s spirit is auto-
matically released to the nearest graveyard (in seconds) (number)
GetRepairAllCost
Returns the cost to repair all of the player’s damaged items.
repairAllCost, canRepair = GetRepairAllCost()
Returns 0, nil if none of the player’s items are damaged. Only returns valid
data while interacting with a vendor which allows repairs (i.e. for whom
CanMerchantRepair() returns 1).
Returns:
repairAllCostCost to repair all damaged items (in copper) (number)
canRepair1if repairs are currently available; otherwise nil (1nil)
GetResSicknessDuration
Returns the duration of resurrection sickness at the player’s current level.
resSicknessTime = GetResSicknessDuration()
Returns nil for players under level 10, who are allowed to resurrect at a spirit
healer without suffering resurrection sickness.
Returns:
resSicknessTimeText describing the duration of resurrection
sickness were the player to resurrect at a spirit healer (string)
784 Part IV Reference
GetRestState
Returns the player’s current rest state.
state, name, multiplier = GetRestState()
Returns:
stateNumber identifying the current rest state (number)
1—Rested
2—Normal
3Tired; used in locales with account play time limits
4Unhealthy; used in locales with account play time limits
nameLocalized text describing the player’s current rest state (string)
multiplierMultiplier for experience points earned from kills (number)
GetRewardHonor
Returns the amount of honor points awarded when completing a quest.
honor = GetRewardHonor()
Only valid when the questgiver UI is showing the accept/decline or
completion stages of a quest dialog (between the QUEST_DETAIL and
QUEST_FINISHED events, or between the QUEST_COMPLETE and
QUEST_FINISHED events); otherwise may return zero or a value from the most
recently displayed quest.
Returns:
honorThe honor points to be awarded (number)
GetRewardMoney
Returns the amount of money awarded when completing a quest.
money = GetRewardMoney()
Only valid when the questgiver UI is showing the accept/decline or
completion stages of a quest dialog (between the QUEST_DETAIL and
QUEST_FINISHED events, or between the QUEST_COMPLETE and
QUEST_FINISHED events); otherwise may return zero or a value from the most
recently displayed quest.
Returns:
moneyThe amount of money to be awarded (in copper) (number)
GetRewardSpell
Returns information about a spell awarded when completing a quest.
texture, name, isTradeskillSpell, isSpellLearned = GetRewardSpell()
Only valid when the questgiver UI is showing the accept/decline or
completion stages of a quest dialog (between the QUEST_DETAIL and
QUEST_FINISHED events, or between the QUEST_COMPLETE and
QUEST_FINISHED events); otherwise may return zero or values from the most
recently displayed quest.
If both isTradeskillSpell and isSpellLearned are nil, the reward is a
spell cast upon the player.
Chapter 27 API Reference 785
Returns:
texturePath to the spell’s icon texture (string)
nameName of the spell (string)
isTradeskillSpell1if the spell is a tradeskill recipe; otherwise nil (1nil)
isSpellLearned1if the reward teaches the player a new spell; otherwise nil
(1nil)
GetRewardTalents
Returns the talent points awarded when completing a quest.
talents = GetRewardTalents()
Only valid when the questgiver UI is showing the accept/decline or
completion stages of a quest dialog (between the QUEST_DETAIL and QUEST
_FINISHED events, or between the QUEST_COMPLETE and QUEST_FINISHED
events); otherwise may return zero or a value from the most recently displayed
quest.
(Very few quests award talent points; currently this functionality is only used
within the Death Knight starting experience.)
Returns:
talentsThe talent points to be awarded (number)
GetRewardText
Returns questgiver dialog to be displayed when completing a quest.
text = GetRewardText()
Only valid when the questgiver UI is showing the completion stage of a quest
dialog (between the QUEST_COMPLETE and QUEST_FINISHED events);
otherwise may return the empty string or a value from the most recently
displayed quest.
Returns:
textText to be displayed for the quest completion dialog (string)
GetRewardTitle
Returns the title awarded when completing a quest.
title = GetRewardTitle()
Only valid when the questgiver UI is showing the accept/decline or
completion stages of a quest dialog (between the QUEST_DETAIL and
QUEST_FINISHED events, or between the QUEST_COMPLETE and QUEST
_FINISHED events); otherwise may return nil or a value from the most recently
displayed quest.
Returns:
titleThe title to be awarded, or nil if the quest does not reward a title
(string)
GetRuneCooldown
Returns cooldown information about one of the player’s rune resources.
start, duration, runeReady = GetRuneCooldown(slot)
786 Part IV Reference
Note the placement of runes 3-4 (normally Unholy) and 5-6 (normally Frost)
are reversed in the default UI. Also note the behavior of returned values differs
slightly from most other GetXYZCooldown-style functions.
Arguments:
slotIndex of a rune slot, as positioned in the default UI: (number)
1—Leftmost
2Second from left
3Fifth from left (second from right)
4Sixth from left (rightmost)
5Third from left
6Fourth from left
Returns:
start—The value of GetTime() at the moment the cooldown began, or 0 if the
rune is ready (number)
durationThe length of the cooldown (regardless of whether the rune is cur-
rently cooling down) (number)
runeReadyTrue iftherunecanbeused;false if the rune is cooling down
(boolean)
GetRuneCount
Returns the number of available rune resources in one of the player’s rune
slots.
count = GetRuneCount(slot)
Returns 1 if a rune is ready and 0 if a rune is on cooldown.
Arguments:
slotIndex of a rune slot, as positioned in the default UI: (number)
1—Leftmost
2Second from left
3Fifth from left (second from right)
4Sixth from left (rightmost)
5Third from left
6Fourth from left
Returns:
countNumber of available runes in the slot (number)
GetRuneType
Returns the type of one of the player’s rune resources.
runeType = GetRuneType(slot)
Note the placement of runes 3-4 (normally Unholy) and 5-6 (normally Frost)
are reversed in the default UI.
Arguments:
slotIndex of a rune slot, as positioned in the default UI: (number)
1—Leftmost
2Second from left
3Fifth from left (second from right)
4Sixth from left (rightmost)
5Third from left
6Fourth from left
Chapter 27 API Reference 787
Returns:
runeTypeType of the rune (number)
1Blood rune
2Unholy rune
3Frost rune
4—Death rune
GetRunningMacro
Returns the index of the currently running macro.
index = GetRunningMacro()
Returns:
indexIndex of the currently running macro, or nil if no macro is running
(number,macroID)
GetRunningMacroButton
Returns the mouse button that was used to activate the running macro.
button = GetRunningMacroButton()
Returns:
buttonName of the mouse button used to activate the macro; always
‘‘LeftButton’’ if the macro was triggered by a key binding (string)
Button4
Button5
LeftButton
MiddleButton
RightButton
GetSavedInstanceInfo
Returns information on a specific instance to which the player is saved.
instanceName, instanceID, instanceReset, instanceDifficulty, locked, i
extended, instanceIDMostSig, isRaid, maxPlayers, difficultyName = i
GetSavedInstanceInfo(index)
Arguments:
indexIndex of a saved instance (between 1and GetNumSavedInstances())
(number)
Returns:
instanceNameName of the instance (string)
instanceIDUnique identifier of the saved instance (commonly known as a
RaidID) (number)
instanceResetApproximate number of seconds remaining until the instance
resets (number)
instanceDifficultyDifficulty level of the saved instance (number)
1Normal (’10 Player’ if instance is a raid)
2Heroic (’25 Player’ if instance is a raid)
3—10 Player Heroic
4—25 Player Heroic
788 Part IV Reference
locked—(boolean)
extendedtrue if the reset time has been extended past its normal time; other-
wise false (boolean)
instanceIDMostSig—(number)
isRaid—(boolean)
maxPlayersNumber of players allowed (number)
difficultyNameA string representing the difficulty of the given instance.
(string)
GetScreenHeight
Returns the height of the screen for UI layout purposes.
height = GetScreenHeight()
Measurements for layout are affected by the UI Scale setting (i.e. the uiscale
CVar) and may not match actual screen pixels.
Returns:
heightHeight of the screen in layout pixels (number)
GetScreenResolutions
Returns a list of available screen resolutions.
... = GetScreenResolutions()
Returns:
...A list of strings, each a description of the dimensions of an avail-
able screen resolution (e.g. “800x600“,“1024x768“)(string)
Example:
-- Print all available screen resolutions:
print(“Available resolutions:“, string.join(“, “, i
GetScreenResolutions()))
GetScreenWidth
Returns the width of the screen for UI layout purposes.
screenWidth = GetScreenWidth()
Measurements for layout are affected by the UI Scale setting (i.e. the uiscale
CVar) and may not match actual screen pixels.
Returns:
screenWidthWidth of the screen in layout pixels (number)
GetScriptCPUUsage
Returns the total CPU time used by the scripting system.
usage = GetScriptCPUUsage()
Only returns valid data if the scriptProfile CVar is set to 1; returns 0
otherwise.
Chapter 27 API Reference 789
Returns:
usageAmount of CPU time used by the scripting system (in milliseconds)
since the UI was loaded or ResetCPUUsage() was last called (number)
GetSelectedAuctionItem
Returns the index of the currently selected item in an auction listing.
index = GetSelectedAuctionItem(“list“)
Auction selection is used only for display and internal recordkeeping in the
default UI; it has no direct effect on other Auction APIs.
Arguments:
listType of auction listing (string)
bidderAuctions the player has bid on
listAuctions the player can browse and bid on or buy out
ownerAuctions the player placed
Returns:
indexIndex of the currently selected auction item (number)
GetSelectedBattlefield
Returns the index of the selected battleground instance in the queueing list.
index = GetSelectedBattlefield()
Selection in the battleground instance list is used only for display in the default
UI and has no effect on other Battlefield APIs.
Returns:
indexIndex of the selection in the battleground queue listing (1for the
first available instance, or between 2 and GetNumBattlefields() for other
instances) (number)
GetSelectedDisplayChannel
Returns the selected channel in the channel list display.
index = GetSelectedDisplayChannel()
Returns:
indexIndex of the selected channel in the display channel list (between 1and
GetNumDisplayChannels())(number)
GetSelectedFaction
Returns which faction entry is selected in the reputation UI.
index = GetSelectedFaction()
Selection has no bearing on other faction-related APIs; this function merely
facilitates behaviors of Blizzard’s reputation UI.
Returns:
indexIndex of an entry in the faction list; between 1and GetNumFactions()
(number)
790 Part IV Reference
GetSelectedFriend
Returns the index of the selected character in the player’s friends list.
index = GetSelectedFriend()
Selection in the Friends list is used only for display in the default UI and has no
effect on other Friends list APIs.
Returns:
indexIndex of the selected character in the Friends list (between 1and
GetNumFriends())(number)
GetSelectedIgnore
Returns the index of the selected character in the player’s ignore list.
index = GetSelectedIgnore()
Selection in the Ignore list is used only for display in the default UI and has no
effect on other Ignore list APIs.
Returns:
indexIndex of the selected character in the Ignore list (between 1and
GetNumIgnores())(number)
GetSelectedMute
Returns the index of the selected entry in the Muted list.
selectedMute = GetSelectedMute()
Mute list selection is only used for display purposes in the default UI and has
no effect on other API functions.
Returns:
selectedMuteIndex of the selected entry in the mute listing (between
1and GetNumMutes()), or 0 if no entry is selected (number)
GetSelectedSkill
Returns the index of the selected skill in the Skills UI.
index = GetSelectedSkill()
Selection is only used for display purposes in the default Skills UI and has no
effect on other Skill APIs.
Returns:
indexIndex of the selected entry in the skills list (between 1and
GetNumSkillLines())(number)
GetSelectedStablePet
Returns the index of the selected stable pet.
selectedPet = GetSelectedStablePet()
Returns:
selectedPetIndex of the currently selected stable pet (number)
-1The player has no pets (in the stables or otherwise)
Chapter 27 API Reference 791
0The active pet is selected
1 to NUM_PET_STABLE_SLOTSA stable slot is selected
GetSendMailCOD
Returns the Cash-On-Delivery cost of the outgoing message.
amount = GetSendMailCOD()
Returns the amount set via SetSendMailCOD(), which in the default UI is
only called once its Send button has been clicked (immediately before sending
the message). Thus, does not return the COD amount set in the default UI’s
Send Mail window.
Returns:
amountCOD cost for the items attached to the message (in copper) (number)
GetSendMailItem
Returns information for an item attached to the outgoing message.
itemName, itemTexture, stackCount, quality = GetSendMailItem(slot)
Arguments:
slotIndex of an outgoing attachment slot (between 1and ATTACHMENTS_MAX
_SEND)(number)
Returns:
itemNameName of the attachment item (string)
itemTexturePathtoanicontexturefortheattachmentitem(string)
stackCountNumber of stacked items (string)
qualityQuality (rarity) of the attachment item (number, itemQuality)
GetSendMailItemLink
Returns a hyperlink for an item attached to the outgoing message.
itemlink = GetSendMailItemLink(slot)
Arguments:
slotIndex of an outgoing attachment slot (between 1and ATTACHMENTS_MAX
_SEND)(number)
Returns:
itemlinkA hyperlink for the attachment item (string, hyperlink)
Example:
-- Scan all the send mail item slots, printing a link for each item
for slot=1,ATTACHMENTS_MAX_SEND do
local link = GetSendMailItemLink(slot)
if link then
print(“Item “ .. link .. “ is in slot “ .. slot)
end
end
GetSendMailMoney
Returns the amount of money to be sent with the outgoing message.
amount = GetSendMailMoney()
792 Part IV Reference
Returns the amount set via SetSendMailMoney(), which in the default UI is
only called once its Send button has been clicked (immediately before sending
the message). Thus, does not return the Send Money amount set in the default
UI’s Send Mail window.
Returns:
amountAmount of money to be sent (in copper) (number)
GetSendMailPrice
Returns the cost to send the outgoing mail message.
price = GetSendMailPrice()
The cost of sending a message rises as more items are attached.
Returns:
priceCost to send the outgoing mail message (in copper) (number)
GetShapeshiftForm
Returns the index of the active ability on the stance/shapeshift bar.
index = GetShapeshiftForm()
Returns:
indexIndex of the active ability on the stance/shapeshift bar (between 1and
GetNumShapeshiftForms())(number)
GetShapeshiftFormCooldown
Returns cooldown information about an ability on the stance/shapeshift bar.
start, duration, enable = GetShapeshiftFormCooldown(index)
Arguments:
indexIndex of an ability on the stance/shapeshift bar (between 1and
GetNumShapeshiftForms())(number)
Returns:
start—The value of GetTime() at the moment the cooldown began, or 0 if the
ability is ready (number)
durationThe length of the cooldown, or 0 if the ability is ready (number)
enable1if a Cooldown UI element should be used to display the cooldown,
otherwise 0. (Does not always correlate with whether the ability is ready.)
(number)
GetShapeshiftFormInfo
Returns information about an ability on the stance/shapeshift bar.
texture, name, isActive, isCastable = GetShapeshiftFormInfo(index)
Arguments:
indexIndex of an ability on the stance/shapeshift bar (between 1and
GetNumShapeshiftForms())(number)
Returns:
texturePath to an icon texture for the ability (string)
nameName of the ability (string)
Chapter 27 API Reference 793
isActive1if the ability is currently active; otherwise nil (1nil)
isCastable1if the ability can currently be used; otherwise nil (1nil)
GetShieldBlock
Returns the amount of damage prevented when the player blocks with a
shield.
damage = GetShieldBlock()
Returns:
damageThe amount of damage prevented when the player blocks with a
shield (number)
GetSkillLineInfo
Returns information about an entry in the Skills UI list.
skillName, header, isExpanded, skillRank, numTempPoints, i
skillModifier, skillMaxRank, isAbandonable, stepCost, rankCost, i
minLevel, skillCostType, skillDescription = GetSkillLineInfo(index)
Arguments:
indexIndex of an entry in the skills list (between 1and GetNumSkill
Lines())(number)
Returns:
skillNameName of the skill (or header) (string)
header1if the entry is a header; nil if the entry is a skill (1nil)
isExpanded1if the entry is a header and currently expanded; otherwise nil
(1nil)
skillRankThe player’s current rank in the skill (number)
numTempPoints—Unused (number)
skillModifierTemporary skill modifier (e.g. due to buffs/debuffs or gear)
(number)
skillMaxRankMaximum rank currently available in the skill (e.g. 395 in a
weapon skill for a level 79 player, 150 for a trade skill in which the player has
reached Journeyman status); 1for unranked skills (e.g. armor proficiencies)
(number)
isAbandonable1if the player can unlearn the skill; otherwise nil (1nil)
stepCost—Unused (number)
rankCost—Unused (number)
minLevel—Unused (number)
skillCostType1for ranked skills; 0 for unranked skills (number)
skillDescriptionExtended description of the skill (string)
GetSocketItemBoundTradeable
Returns whether the item open for socketing is temporarily tradeable.
tradeable = GetSocketItemBoundTradeable()
794 Part IV Reference
A Bind on Pickup item looted by the player can be traded to other characters
who were originally eligible to loot it, but only within a limited time after
looting. This period can be ended prematurely if the player attempts certain
actions (such as socketing gems into the item).
Returns:
tradeable1if the item can temporarily be traded to other players; otherwise
nil (1nil)
GetSocketItemInfo
Returns information about the item currently being socketed.
name, icon, quality = GetSocketItemInfo()
Only returns valid information when the Item Socketing UI is open (i.e.
between the SOCKET_INFO_UPDATE and SOCKET_INFO_CLOSE events).
Returns:
name—Name of the item (string)
iconPathtoanicontexturefortheitem(string)
qualityQuality level of the item (number, itemQuality)
GetSocketItemRefundable
Returns whether the item open for socketing is temporarily refundable.
refundable = GetSocketItemRefundable()
Items bought with alternate currency (honor points, arena points, or special
items such as Emblems of Heroism and Dalaran Cooking Awards) can be
returned to a vendor for a full refund, but only within a limited time after the
original purchase. This period can be ended prematurely if the player attempts
certain actions (such as socketing gems into the item).
Returns:
refundable1if the item can be returned to a vendor for a refund; otherwise
nil (1nil)
GetSocketTypes
Returns information about the gem types usable in a socket.
gemColor = GetSocketTypes(index)
Only returns valid information when the Item Socketing UI is open (i.e.
between the SOCKET_INFO_UPDATE and SOCKET_INFO_CLOSE events).
Arguments:
indexIndex of a gem socket (between 1and GetNumSockets())(number)
Returns:
gemColorType of the gem socket (string)
BlueAccepts any gem, but requires a blue, green, purple or prismatic gem
to activate the item’s socket bonus
Chapter 27 API Reference 795
MetaAccepts only meta gems
RedAccepts any gem, but requires a red, purple, orange or prismatic gem to
activate the item’s socket bonus
SocketAccepts any gem
YellowAccepts any gem, but requires a yellow, orange, green or prismatic
gem to activate the item’s socket bonus
GetSpellAutocast
Returns information about automatic casting for a spell in the spellbook.
autocastAllowed, autocastEnabled = GetSpellAutocast(id, “bookType“)
Generally, only certain pet spells can be autocast.
Arguments:
idIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
Returns:
autocastAllowed1if automatic casting is allowed for the action; otherwise
nil (1nil)
autocastEnabled1if automatic casting is currently turned on for the action;
otherwise nil (1nil)
GetSpellBonusDamage
Returns the player’s spell damage bonus for a spell school.
minModifier = GetSpellBonusDamage(school)
Arguments:
schoolIndex of a spell school (number)
1—Physical
2—Holy
3—Fire
4—Nature
5—Frost
6Shadow
7—Arcane
Returns:
minModifierThe player’s spell damage bonus for the given school (number)
GetSpellBonusHealing
Returns the player’s amount of bonus healing.
bonusHealing = GetSpellBonusHealing()
Returns:
bonusHealingAmount of bonus healing (integer)
796 Part IV Reference
GetSpellCooldown
Returns cooldown information about a spell in the spellbook.
start, duration, enable = GetSpellCooldown(index, “bookType“) or i
GetSpellCooldown(“name“)
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
Returns:
start—The value of GetTime() at the moment the cooldown began, or 0 if the
spell is ready (number)
durationThe length of the cooldown, or 0 if the spell is ready (number)
enable1if a Cooldown UI element should be used to display the cooldown,
otherwise 0. (Does not always correlate with whether the spell is ready.)
(number)
GetSpellCount
Returns the number of times a spell can be cast.
numCasts = GetSpellCount(index, “bookType“) or GetSpellCount(“name“)
Generally used for spells whose casting is limited by the number of item
reagents in the player’s possession.
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
Returns:
numCastsNumber of times the spell can be cast, or 0 if unlimited (number)
Example:
-- print a list of reagent-limited spells in the player’s spellbook
local numTabs = GetNumSpellTabs()
for tabid=1,numTabs do
local name,texture,offset,numSpells = GetSpellTabInfo(tabid)
for spellid=1,numSpells do
local name,rank = GetSpellName(spellid + offset, “book“)
local count = GetSpellCount(spellid + offset, “book“)
if count > 0 then
print(name .. “ ( “.. count .. “ casts)“)
Chapter 27 API Reference 797
end
end
end
GetSpellCritChance
Returns the player’s spell critical strike chance for a spell school.
minCrit = GetSpellCritChance(school)
Arguments:
schoolIndex of a spell school (number)
1—Physical
2—Holy
3—Fire
4—Nature
5—Frost
6Shadow
7—Arcane
Returns:
minCritThe player’s percentage critical strike chance for spells from the
given school (number)
GetSpellCritChanceFromIntellect
Returns additional spell critical strike chance provided by Intellect.
critChance = GetSpellCritChanceFromIntellect([“unit“])
Arguments:
unit (optional)A unit to query; only valid for player and pet,defaultsto
player if omitted (string,unitID)
Returns:
critChanceAdditional percentage chance of spell critical strikes conferred by
the unit’s Intellect statistic (number)
GetSpellInfo
Returns information about a spell.
name, rank, icon, powerCost, isFunnel, powerType, castingTime, i
minRange, maxRange = GetSpellInfo(index, “bookType“) or i
GetSpellInfo(“name“) or GetSpellInfo(id)
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell, optionally including secondary text (e.g. ‘‘Mana
Burn’’ to find the player’s highest rank, or ‘‘Mana Burn(Rank 2)’’no
space before the parenthesisfor a specific rank) (string)
idNumeric ID of a spell (number, spellID)
798 Part IV Reference
Returns:
nameName of the spell (string)
rankSecondary text associated with the spell (e.g. ‘‘Rank 5’’, ‘‘Racial’’, etc.)
(string)
iconPathtoanicontextureforthespell(string)
powerCostAmount of mana, rage, energy, runic power, or focus required to
cast the spell (number)
isFunnelTrue for spells with health funneling effects (like Health Funnel)
(boolean)
powerTypePower type to cast the spell (number)
-2—Health
0—Mana
1—Rage
2—Focus
3—Energy
5—Runes
6Runic Power
castingTimeCasting time of the spell in milliseconds (number)
minRangeMinimum range from the target required to cast the spell (number)
maxRangeMaximum range from the target at which you can cast the spell
(number)
GetSpellLink
Returns a hyperlink for a spell.
link, tradeLink = GetSpellLink(index, “bookType“) or i
GetSpellLink(“name“) or GetSpellLink(id)
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell, optionally including secondary text (e.g. ‘‘Mana
Burn’’ to find the player’s highest rank, or ‘‘Mana Burn(Rank 2)’’no
space before the parenthesisfor a specific rank) (string)
idNumeric ID of a spell (number, spellID)
Returns:
linkA hyperlink for the spell (string, hyperlink)
tradeLinkA hyperlink representing the player’s list of trade skill recipes, if
the spell is a trade skill (i.e. if ‘‘casting’’ the spell opens a trade skill window)
(string)
GetSpellName
Returns the name and secondary text for a spell in the spellbook.
spellName, subSpellName = GetSpellName(id, “bookType“)
Chapter 27 API Reference 799
Arguments:
idIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
Returns:
spellNameLocalized name of the spell (string)
subSpellNameSecondary text associated with the spell (e.g. ‘‘Rank 5’’, ‘‘Racial
Passive’’, ‘‘Artisan’’) (string)
GetSpellPenetration
Returns the amount of enemy magic resistance ignored due to the player’s
Spell Penetration Rating.
penetration = GetSpellPenetration()
Returns:
penetrationAmount of enemy magic resistance ignored due to the player’s
Spell Penetration Rating (number)
GetSpellTabInfo
Returns information about a tab in the spellbook.
name, texture, offset, numSpells = GetSpellTabInfo(index)
Arguments:
indexIndex of a spellbook tab (between 1and GetNumSpellTabs())
(number)
Returns:
nameName of the spellbook tab (string)
texturePath to an icon texture for the spellbook tab (string)
offsetspellbookID of the first spell to be listed under the tab (number)
numSpellsNumber of spells listed under the tab (number)
Example:
-- Print the valid spellIds for each tab
local numTabs = GetNumSpellTabs()
for i=1,numTabs do
local name,texture,offset,numSpells = GetSpellTabInfo(i)
print(“Spell tab \““ .. name .. “\“ contains spells from id “ i
.. offset + 1 .. “ through “ .. offset + numSpells)
end
GetSpellTexture
Returns the icon texture path for a spell.
texture = GetSpellTexture(index, “bookType“) or GetSpellTexture(“name“)
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
800 Part IV Reference
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
Returns:
texturePathtoanicontextureforthespell(string)
GetStablePetFoodTypes
Returns the types of food that a stabled pet will eat.
... = GetStablePetFoodTypes(index)
Arguments:
index—Index of a stable slot (number)
0—Active pet
1 to NUM_PET_STABLE_SLOTSA stabled pet
Returns:
...A list of strings, each the localized name of a food type the pet will eat
(list)
GetStablePetInfo
Returns information about a stabled pet.
icon, name, level, family, talent = GetStablePetInfo(index)
Arguments:
index—Index of a stable slot (number)
0—Active pet
1 to NUM_PET_STABLE_SLOTSA stable slot
Returns:
iconPathtoanicontextureforthepet(string)
name—Name of the pet (string)
levelLevel of the pet (number)
familyLocalized name of the pet’s creature family (e.g. Cat, Bear, Chimaera)
(string)
talentLocalized name of the pet’s talent tree (e.g. Ferocity, Tenacity, Cun-
ning) (string)
GetStatistic
Returns data for a statistic.
info = GetStatistic(id)
Arguments:
idThe numeric ID of a statistic (number)
Returns:
infoThe data for the statistic, or ‘‘--’’ if none has yet been recorded for it
(string)
Chapter 27 API Reference 801
GetStatisticsCategoryList
Returns a list of all statistic categories.
categories = GetStatisticsCategoryList()
Returns:
categoriesA list of statistic category IDs (table)
GetSubZoneText
Returns the name of the minor area in which the player is located.
subzoneText = GetSubZoneText()
Subzones are named regions within a larger zone or instance: e.g. the Valley of
Trials in Durotar, the Terrace of Light in Shattrath City, or the Njorn Stair in
Utgarde Keep.
Returns:
subzoneTextName of the current subzone (string)
GetSuggestedGroupNum
Returns the suggested group size for attempting the quest currently
offered by a questgiver.
suggestedGroup = GetSuggestedGroupNum()
Usable following the QUEST_DETAIL event in which the questgiver presents
the player with the details of a quest and the option to accept or decline.
Returns:
suggestedGroupSuggested group size for attempting the quest currently
offered by a questgiver (number)
GetSummonConfirmAreaName
Returns the destination area of an offered summons.
area = GetSummonConfirmAreaName()
The name returned is generally that of the subzone in which the summoner
performed the spell.
Usable between when the CONFIRM_SUMMON event fires (due to a summoning
spell cast by another player) and when the value returned by
GetSummonConfirmTimeLeft() reaches zero.
Returns:
areaName of the location to which the player will be teleported upon accept-
ing the summons (string)
GetSummonConfirmSummoner
Returns the name of the unit offering a summons to the player.
text = GetSummonConfirmSummoner()
Usable between when the CONFIRM_SUMMON event fires (due to a summoning
spell cast by another player) and when the value returned by
GetSummonConfirmTimeLeft() reaches zero.
802 Part IV Reference
Returns:
textName of the summoning unit (string)
GetSummonConfirmTimeLeft
Returns the amount of time remaining before an offered summons expires.
timeleft = GetSummonConfirmTimeLeft()
Returns 0 if no summons is currently available.
Returns:
timeleftTime remaining until the offered summons can no longer be
accepted (in seconds) (number)
GetSummonFriendCooldown
Returns cooldown information about the player’s Summon Friend ability.
start, duration = GetSummonFriendCooldown()
Returns:
start—The value of GetTime() at the moment the cooldown began, or 0 if the
ability is ready (number)
durationThe length of the cooldown, or 0 if the ability is ready (number)
GetTabardCreationCost
Returns the cost to create a guild tabard.
cost = GetTabardCreationCost()
Only returns valid data if the player is interacting with a tabard designer (i.e.
between the OPEN_TABARD_FRAME and CLOSE_TABARD_FRAME events).
Returns:
costThe cost of creating a guild tabard, in copper (number)
GetTalentInfo
Returns information about a talent option.
name, iconTexture, tier, column, rank, maxRank, isExceptional, i
meetsPrereq, previewRank, meetsPreviewPrereq = i
GetTalentInfo(tabIndex, talentIndex, inspect, pet, talentGroup)
Arguments:
tabIndexIndex of a talent tab (between 1and GetNumTalentTabs())
(number)
talentIndexIndex of a talent option (between 1and GetNumTalents())
(number)
inspecttrue to return information for the currently inspected
unit; false to return information for the player (boolean)
pettrue to return information for the player’s pet; false to return informa-
tion for the player (boolean)
talentGroupWhich set of talents to edit, if the player has Dual Talent Special-
ization enabled (number)
1Primary Talents
Chapter 27 API Reference 803
2—Secondary Talents
nilCurrently active talents
Returns:
nameName of the talent (string)
iconTextureThe icon texture of the talent. (string)
tierRow in which the talent should be displayed (1=top) (number)
columnColumn in which the talent should be displayed (1=left) (number)
rankNumber of points spent in the talent (number)
maxRankMaximum number of points that can be spent in the talent (number)
isExceptional1if the talent confers a new ability (spell); otherwise nil
(1nil)
meetsPrereq1if the prerequisites to learning the talent have been met; other-
wise nil (1nil)
previewRankNumber of points spent in the talent in preview mode (number)
meetsPreviewPrereq1if the prerequisites to learning the talent have been
met in preview mode; otherwise nil (1nil)
GetTalentLink
Returns a hyperlink for a talent.
link = GetTalentLink(tabIndex, talentIndex, inspect, pet, talentGroup)
Arguments:
tabIndexIndex of a talent tab (between 1and GetNumTalentTabs())
(number)
talentIndexIndex of a talent option (between 1and GetNumTalents())
(number)
inspecttrue to return information for the currently inspected
unit; false to return information for the player (boolean)
pettrue to return information for the player’s pet; false to return informa-
tion for the player (boolean)
talentGroupWhich set of talents to edit, if the player has Dual Talent Special-
ization enabled (number)
1Primary Talents
2—Secondary Talents
nilCurrently active talents
Returns:
linkA hyperlink representing the talent and the number of points spent in it
(string, hyperlink)
GetTalentPrereqs
Returns information about prerequisites to learning a talent.
tier, column, isLearnable, isPreviewLearnable, ... = i
GetTalentPrereqs(tabIndex, talentIndex, inspect, pet, talentGroup)
804 Part IV Reference
Arguments:
tabIndexIndex of a talent tab (between 1and GetNumTalentTabs())
(number)
talentIndexIndex of a talent option (between 1and GetNumTalents())
(number)
inspecttrue to return information for the currently inspected
unit; false to return information for the player (boolean)
pettrue to return information for the player’s pet; false to return informa-
tion for the player (boolean)
talentGroupWhich set of talents to edit, if the player has Dual Talent Special-
ization enabled (number)
1Primary Talents
2—Secondary Talents
nilCurrently active talents
Returns:
tierRow in which the talent’s prerequisite is displayed (1=top) (number)
columnColumn in which the talent’s prerequisite is displayed (1=left)
(number)
isLearnable1if the talent is learnable; otherwise nil (1nil)
isPreviewLearnable1if the talent is learnable in preview mode; otherwise
nil (1nil)
...Additional sets of tier, column, isLearnable, isPreviewLearnable
values for each prerequisite to learning the talent (list)
GetTalentTabInfo
Returns information about a talent tab.
name, icon, points, background, previewPoints = i
GetTalentTabInfo(tabIndex, inspect, pet, talentGroup)
Arguments:
tabIndexIndex of a talent tab (between 1and GetNumTalentTabs())
(number)
inspecttrue to return information for the currently inspected
unit; false to return information for the player (boolean)
pettrue to return information for the player’s pet; false to return informa-
tion for the player (boolean)
talentGroupWhich set of talents to edit, if the player has Dual Talent Special-
ization enabled (number)
1Primary Talents
2—Secondary Talents
nilCurrently active talents
Returns:
nameName of the talent tab (string)
iconPath to an icon texture for the talent tab (string)
Chapter 27 API Reference 805
pointsNumber of points spent in the talent tab (number)
backgroundPath to a background texture for the talent tab (string)
previewPointsNumber of points spent in the talent tab in preview mode
(number)
GetTargetTradeMoney
Returns the amount of money offered for trade by the target.
amount = GetTargetTradeMoney()
Returns:
amountAmount of money offered for trade by the target (in copper)
(number)
GetTaxiBenchmarkMode
Returns whether flight path benchmark mode is enabled.
isBenchmark = GetTaxiBenchmarkMode()
Returns:
isBenchmark1if taxi benchmark mode is enabled; otherwise nil (1nil)
GetTerrainMip
Returns the level of terrain detail displayed.
terrainDetail = GetTerrainMip()
Corresponds to the ‘‘Terrain Blending’’ slider in the default UI’s Video Options
pane.
Returns:
terrainDetailLevel of terrain detail displayed (number)
0—Low detail
1—High detail
GetText
Returns a localized string according to given parameters.
text = GetText(“token“ [, gender [, ordinal]])
Applies to any global variable whose name fits a standard format: for example,
GetText(“foo“) returns the value of the global variable foo (if it exists), and
GetText(“foo“, 3) returns the value of foo_FEMALE (or if it does not exist,
the value of foo). Causes a Lua error if the given variable does not exists (or is
nil).
Arguments:
tokenBase name of a localized string token (string)
gender (optional)Gender of the string’s subject (as returned by UnitSex())
(number)
ordinal (optional)Currently unused (number)
Returns:
textThe localized string according to the given parameters (string)
806 Part IV Reference
Example:
GetText(“FACTION_STANDING_LABEL1“)
-- returns the value of “FACTION_STANDING_LABEL1“
-- (“Hated“ on enUS clients)
GetText(“FACTION_STANDING_LABEL1“,3)
-- returns the value of “FACTION_STANDING_LABEL1_FEMALE“
-- (“Hated“ on enUS clients, but distinct from the male form in
-- certain other locales)
GetThreatStatusColor
Returns color values for a given threat status.
red, green, blue = GetThreatStatusColor(status)
Color component values are floating point numbers between 0 and 1, with 1
representing full intensity.
Arguments:
statusA threat status category, as returned by UnitThreatSituation or
UnitDetailedThreatSituation (number)
Returns:
redRed component of the color (number)
greenGreen component of the color (number)
blueBlue component of the color (number)
GetTime
Returns a number representing the current time (with millisecond precision).
time = GetTime()
Unlike with time(), the number returned by this function has no meaning of
its own and may not be comparable across clients; however, since it also
provides higher resolution it can be compared against itself for high-precision
time measurements.
Returns:
timeA number that represents the current time in seconds (with millisecond
precision) (number)
GetTitleName
Returns the text of an available player title.
titleName = GetTitleName(titleIndex)
Arguments:
titleIndexIndex of a title available to the player (between 1and
GetNumTitles())(integer)
Returns:
titleNameThe text of the title (string)
Example:
-- Print all available titles
Chapter 27 API Reference 807
for i=1,GetNumTitles() do
print(GetTitleName(i))
end
GetTitleText
Returns the title text for the quest presented by a questgiver.
text = GetTitleText()
Only valid following the QUEST_DETAIL,QUEST_PROGRESS,or
QUEST_COMPLETE events; otherwise may return nil or a value from the most
recently displayed quest.
Returns:
textTitle text for the quest (string)
GetTotalAchievementPoints
Returns the player’s total achievement points earned.
points = GetTotalAchievementPoints()
Returns:
pointsTotal number of achievement points earned by the player (number)
GetTotemInfo
Returns information on a currently active totem (or ghoul).
haveTotem, name, startTime, duration, icon = GetTotemInfo(slot)
Totem functions are also used for ghouls summoned by a Death Knight’s Raise
Dead ability (if the ghoul is not made a controllable pet by the Master of
Ghouls talent).
Arguments:
slotWhich totem to query (number)
1Fire (or Death Knight’s ghoul)
2—Earth
3—Water
4—Air
Returns:
haveTotemTrue if a totem of the given type is active (boolean)
nameThe name of the totem (string)
startTimeThe value of GetTime() when the totem was created (number)
durationThe total duration the totem will last (in seconds) (number)
iconPath to a texture to use as the totem’s icon (string)
GetTotemTimeLeft
Returns the time remaining before a totem (or ghoul) automatically disappears.
seconds = GetTotemTimeLeft(slot)
Using GetTime() and the third and fourth returns (startTime and
duration)ofGetTotemInfo() instead of this function is recommended if
frequent updates are needed.
808 Part IV Reference
Totem functions are also used for ghouls summoned by a Death Knight’s Raise
Dead ability (if the ghoul is not made a controllable pet by the Master of
Ghouls talent).
Arguments:
slotWhich totem to query (number)
1Fire (or Death Knight’s ghoul)
2—Earth
3—Water
4—Air
Returns:
secondsTime remaining before the totem/ghoul is automatically destroyed
(number)
GetTrackedAchievements
Returns numeric IDs of the achievements flagged for display in the objectives
tracker UI.
... = GetTrackedAchievements()
Returns:
...List of numeric IDs for the achievements being tracked (list)
GetTrackingInfo
Returns information about a given tracking option.
name, texture, active, category = GetTrackingInfo(index)
Arguments:
indexIndex of a tracking ability to query (between 1and GetNumTracking
Types())(number)
Returns:
nameLocalized name of the tracking ability (string)
texturePath to an icon texture for the tracking ability (string)
active1if the tracking abilty is active; otherwise nil (1nil)
categoryCategory of the tracking ability; used in the default UI
to determine whether to strip the border from the ability’s icon tex-
ture, and also indicates when the ability can be used: (string)
otherAbility is available to all players and can be used at any time
spellAbility is a spell from the player’s spellbook; using it may be subject
to spell casting restrictions
GetTrackingTexture
Returns the texture of the active tracking ability.
texture = GetTrackingTexture()
Returns ‘‘Interface\Minimap\Tracking\None’’ if no tracking ability is active.
Returns:
texturePath to an icon texture for the active tracking ability (string)
Chapter 27 API Reference 809
GetTradePlayerItemInfo
Returns information about an item offered for trade by the player.
name, texture, numItems, quality, isUsable, enchantment = i
GetTradePlayerItemInfo(index)
Arguments:
indexIndex of an item slot on the player’s side of the trade window (between
1and MAX_TRADE_ITEMS)(number)
Returns:
name—Name of the item (string)
texturePathtoanicontexturefortheitem(string)
numItemsNumber of stacked items in the slot (number)
qualityQuality (rarity) level of the item (number, itemQuality)
isUsable1if the player character can use or equip the item; otherwise nil
(1nil)
enchantmentName of the enchantment being applied to the item through
trade; otherwise nil (string)
GetTradePlayerItemLink
Returns a hyperlink for an item offered for trade by the player.
link = GetTradePlayerItemLink(index)
Arguments:
indexIndex of an item offered for trade by the player (between 1and
MAX_TRADE_ITEMS)(number)
Returns:
linkA hyperlink for the item (string, hyperlink)
GetTradeSkillCooldown
Returns the time remaining on a trade skill recipe’s cooldown.
cooldown = GetTradeSkillCooldown(index)
Arguments:
indexIndex of a recipe in the trade skill list (between 1and GetNumTrade
Skills())(number)
Returns:
cooldownTime remaining before the recipe can be performed again (in sec-
onds), or nil if the recipe is currently available or has no cooldown (number)
Example:
-- Print cooldowns for any applicable recipes
for i=1,GetNumTradeSkills() do
local cooldown = GetTradeSkillCooldown(i)
if cooldown then
local name = GetTradeSkillInfo(i)
print(“Cooldown remaining for “ .. i
name .. “: “ .. SecondsToTime(cooldown))
end
end
810 Part IV Reference
GetTradeSkillDescription
Returns descriptive text for a tradeskill recipe.
description = GetTradeSkillDescription(index)
Most recipes that create items don’t provide descriptive text; descriptions are
more often used for enchants and special recipes such as inscription or
alchemy research.
Arguments:
indexIndex of a recipe in the trade skill list (between 1and GetNumTrade
Skills())(number)
Returns:
descriptionDescriptive text for the tradeskill recipe, or nil if no text is asso-
ciated with the recipe (string)
GetTradeSkillIcon
Returns the icon for a trade skill recipe.
texturePath = GetTradeSkillIcon(index)
For recipes that create an item, this is generally the icon of the item created; for
other recipes (such as enchants and alchemy/inscription research) a generic
icon is used.
Arguments:
indexIndex of a recipe in the trade skill list (between 1and GetNumTrade
Skills())(number)
Returns:
texturePathPathtoanicontexturefortherecipe(string)
GetTradeSkillInfo
Returns information about a trade skill header or recipe.
skillName, skillType, numAvailable, isExpanded, serviceType = i
GetTradeSkillInfo(index)
Arguments:
indexIndex of an entry in the trade skill list (between 1and
GetNumTradeSkills())(number)
Returns:
skillName—Name of the entry (string)
skillTypeIndicates whether the entry is a header or recipe and difficulty of
recipes (string)
easyLow chance for the player to gain skill by performing the recipe (dis-
played as green in the default UI)
headerThis entry is a header and not an actual trade skill recipe
mediumModerate chance for the player to gain skill by per-
forming the recipe (displayed as yellow in the default UI)
optimalHigh chance for the player to gain skill by performing the recipe
(displayed as orange in the default UI)
Chapter 27 API Reference 811
trivialNo chance for the player to gain skill by performing the recipe
(displayed as gray in the default UI)
numAvailableNumber of times the player can repeat the recipe given avail-
able reagents (number)
isExpanded1if the entry is a header and is expanded; otherwise nil (1nil)
serviceTypeIndicates what type of service the recipe provides (items,
enhancements, etc ... )(
string)
EmbossApplies an emboss (leatherworkers)
EmbroiderApplies an embroider (tailors)
EnchantApplies an enchant (enchanters)
EngraveEngraves a rune (runeforging)
InscribePuts an inscription (scribers)
ModifyPuts a socket (blacksmiths)
TinkerPuts a device like webbing or flexweave (engineers)
nil—Produces an item
GetTradeSkillInvSlotFilter
Returns whether the trade skill listing is filtered by a given item
equipment slot.
enabled = GetTradeSkillInvSlotFilter(index)
Arguments:
indexIndex of an item equipment slot (in the list returned by
GetTradeSkillInvSlots()), or 0for the ‘‘All’’ filter (number)
Returns:
enabled1if the filter is enabled; otherwise nil (1nil)
GetTradeSkillInvSlots
Returns a list of recipe equipment slots for the current trade skill.
... = GetTradeSkillInvSlots()
These inventory types correspond to those of the items produced (see
GetItemInfo() and GetAuctionItemInvTypes())andcanbeusedtolter
the recipe list.
Returns:
...A list of strings, each the localized name of an inventory type applicable to
the current trade skill listing (list)
GetTradeSkillItemLevelFilter
Returns the current settings for filtering the trade skill listing by required level
of items produced.
minLevel, maxLevel = GetTradeSkillItemLevelFilter()
Returns:
minLevelLowest required level of items to show in the filtered list (number)
maxLevelHighest required level of items to show in the filtered list (number)
812 Part IV Reference
GetTradeSkillItemLink
Returns a hyperlink for the item created by a tradeskill recipe.
link = GetTradeSkillItemLink(index)
The tooltip produced when resolving the link describes only the item created
by the recipe. For a link which describes the recipe itself (its reagents and
description), see GetTradeSkillRecipeLink().
If the recipe does not create an item, this function returns the same hyperlink as
does GetTradeSkillRecipeLink() (though the text of the link may differ).
Arguments:
indexIndex of a recipe in the trade skill list (between 1and GetNumTrade
Skills())(number)
Returns:
linkA hyperlink for the item created by the recipe (string)
GetTradeSkillItemNameFilter
Returns the current search text for filtering the trade skill listing by name.
text = GetTradeSkillItemNameFilter()
Returns:
textText to search for in recipe names, produced item names or
descriptions, or reagents; nil if no search filter is in use (string)
GetTradeSkillLine
Returns information about the current trade skill.
tradeskillName, rank, maxLevel = GetTradeSkillLine()
Returns:
tradeskillNameName of the trade skill (string)
rankThe character’s current rank in the trade skill (number)
maxLevelThe character’s current maximum rank in the trade skill (e.g. 300 for
a character of Artisan status) (number)
GetTradeSkillListLink
Returns a hyperlink to the player’s list of recipes for the current trade skill.
link = GetTradeSkillListLink()
Returns:
linkA hyperlink other players can resolve to see the player’s full list of
tradeskill recipes (string, hyperlink)
GetTradeSkillNumMade
Returns the number of items created when performing a tradeskill recipe.
minMade, maxMade = GetTradeSkillNumMade(index)
Arguments:
indexIndex of a recipe in the trade skill list (between 1and GetNumTrade
Skills())(number)
Chapter 27 API Reference 813
Returns:
minMadeMinimum number of items created when performing the recipe
(number)
maxMadeMaximum number of items created when performing the recipe
(number)
Example:
-- Print any multi-item recipes
local numSkills = GetNumTradeSkills()
for i=1,numSkills do
local minMade,maxMade = GetTradeSkillNumMade(i)
if minMade > 1 then
local link = GetTradeSkillRecipeLink(i)
if (minMade == maxMade) then
print(link .. “ always creates “ .. minMade .. “ items“)
else
print(link .. “ randomly creates between “ .. minMade .. i
“ and “ .. maxMade .. “ items“)
end
end
end
GetTradeSkillNumReagents
Returns the number of different reagents required for a trade skill recipe.
numReagents = GetTradeSkillNumReagents(index)
Arguments:
indexIndex of a recipe in the trade skill list (between 1and GetNumTrade
Skills())(number)
Returns:
numReagentsNumber of different reagents required for the recipe (number)
GetTradeSkillReagentInfo
Returns information about a reagent in a trade skill recipe.
reagentName, reagentTexture, reagentCount, playerReagentCount = i
GetTradeSkillReagentInfo(skillIndex, reagentIndex)
Arguments:
skillIndexIndex of a recipe in the trade skill list (between 1and
GetNumTradeSkills())(number)
reagentIndexIndex of a reagent in the recipe (between 1and
GetTradeSkillNumReagents())(number)
Returns:
reagentNameName of the reagent (string)
reagentTexturePathtoanicontextureforthereagent(string)
reagentCountQuantity of the reagent required to perform the recipe
(number)
814 Part IV Reference
playerReagentCountQuantity of the reagent in the player’s possession
(number)
Example:
-- Prints the reagent(s) required for the first trade skill
-- recipe listed
local skillIndex = GetFirstTradeSkill()
local name = GetTradeSkillInfo(skillIndex)
print(format(“%s takes the following reagent(s):“, name))
for reagentIndex = 1, GetTradeSkillNumReagents(skillIndex) do
local reagentName, _, reagentCount = i
GetTradeSkillReagentInfo(skillIndex, reagentIndex)
print(format(“ %dx %s“, reagentCount, reagentName))
end
GetTradeSkillReagentItemLink
Returns a hyperlink for a reagent in a tradeskill recipe.
link = GetTradeSkillReagentItemLink(skillIndex, reagentIndex)
Arguments:
skillIndexIndex of a recipe in the trade skill list (between 1and
GetNumTradeSkills())(number)
reagentIndexIndex of a reagent in the recipe (between 1and
GetTradeSkillNumReagents())(number)
Returns:
linkA hyperlink for the reagent item (string, hyperlink)
GetTradeSkillRecipeLink
Returns hyperlink for a tradeskill recipe.
link = GetTradeSkillRecipeLink(index)
The tooltip produced when resolving the link describes the recipe itselfits
reagents and (if present) descriptionin addition to (if applicable) the item
created. For a link which only describes the created item, see GetTradeSkill
ItemLink().
Arguments:
indexIndex of a recipe in the trade skill list (between 1and GetNumTrade
Skills())(number)
Returns:
linkA hyperlink for the trade skill recipe (string)
GetTradeSkillSelectionIndex
Returns the index of the currently selected trade skill recipe.
index = GetTradeSkillSelectionIndex()
Selection in the recipe list is used only for display in the default UI and has no
effect on other Trade Skill APIs.
Chapter 27 API Reference 815
Returns:
indexIndex of the selected recipe in the trade skill list (between 1and
GetNumTradeSkills())(number)
GetTradeSkillSubClassFilter
Returns whether the trade skill listing is filtered by a given item subclass.
enabled = GetTradeSkillSubClassFilter(index)
Arguments:
indexIndex of an item subclass (in the list returned by GetTradeSkill
SubClasses()), or 0for the ‘‘All’’ filter (number)
Returns:
enabled1if the filter is enabled; otherwise nil (1nil)
GetTradeSkillSubClasses
Returns a list of recipe subclasses for the current trade skill.
... = GetTradeSkillSubClasses()
These subclasses correspond to those of the items produced (see
GetItemInfo() and GetAuctionItemSubClasses())andcanbeusedto
filter the recipe list.
Returns:
...A list of strings, each the localized name of an item or recipe
subclass applicable to the current trade skill listing (list)
GetTradeSkillTools
Returns a list of required tools for a trade skill recipe.
toolName, hasTool, ... = GetTradeSkillTools(index)
A tool may be an item (e.g. Blacksmith Hammer, Virtuoso Inking Set) the
player must possess, or a description of a generic (e.g. near an Anvil, in a
Moonwell) or specific (e.g. Netherstorm, Emerald Dragonshrine) location to
which the player must travel in order to perform the recipe. The hasTool
return is only valid for the tools the player can possess.
Arguments:
indexIndex of a recipe in the trade skill list (between 1and GetNumTrade
Skills())(number)
Returns:
toolNameName of the required tool (string)
hasTool1if the tool is an item in the player’s possession; otherwise nil
(1nil)
...An additional toolName, hasTool pair for each tool required (list)
GetTradeTargetItemInfo
Returns information about an item offered for trade by the target.
name, texture, numItems, quality, isUsable, enchantment = i
GetTradeTargetItemInfo(index)
816 Part IV Reference
Arguments:
indexIndex of an item slot on the player’s side of the trade window
(between 1and MAX_TRADE_ITEMS)(number)
Returns:
name—Name of the item (string)
texturePathtoanicontexturefortheitem(string)
numItemsNumber of stacked items in the slot (number)
qualityQuality (rarity) level of the item (number, itemQuality)
isUsable1if the player character can use or equip the item; otherwise nil
(1nil)
enchantmentName of the enchantment being applied to the item through
trade; otherwise nil (string)
GetTradeTargetItemLink
Returns a hyperlink for an item offered for trade by the target.
link = GetTradeTargetItemLink(index)
Arguments:
indexIndex of an item offered for trade by the target (between 1and
MAX_TRADE_ITEMS)(number)
Returns:
linkA hyperlink for the item (string, hyperlink)
GetTradeskillRepeatCount
Returns the number of times the trade skill recipe currently being performed
will repeat.
repeatCount = GetTradeskillRepeatCount()
Returns 1 if a recipe is not being performed; after DoTradeSkill() is called,
returns the number of repetitions queued (which decrements as each repetition
is finished).
Returns:
repeatCountNumber of times the current recipe will repeat (number)
GetTrainerGreetingText
Returns the current trainer’s greeting text.
text = GetTrainerGreetingText()
In the default UI, this text is displayed at the top of the trainer window.
May return the empty string or the last used trainer’s greeting text if called
while not interacting with a trainer.
Returns:
textGreeting text for the trainer with whom the player is currently interact-
ing (string)
GetTrainerSelectionIndex
Returns the index of the currently selected trainer service.
selectionIndex = GetTrainerSelectionIndex()
Chapter 27 API Reference 817
Selection in the recipe list is used only for display in the default UI and has no
effect on other Trade Skill APIs.
Returns:
selectionIndexIndex of the selected entry in the trainer service
listing (between 1and GetNumTrainerServices())(number)
GetTrainerServiceAbilityReq
Returns information about an ability required for purchasing a trainer service.
ability, hasReq = GetTrainerServiceAbilityReq(index, abilityIndex)
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
abilityIndexIndex of one of the service’s ability requirements
(between 1and GetTrainerServiceNumAbilityReq(index))(number)
Returns:
abilityName of the required ability (string)
hasReq1if the player has the required ability; otherwise nil (1nil)
GetTrainerServiceCost
Returns the cost to purchase a trainer service.
moneyCost, talentCost, skillCost = GetTrainerServiceCost(index)
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
Returns:
moneyCostAmount of money required to purchase the service (in copper)
(number)
talentCostNumber of talent points required to purchase the service (gener-
ally unused) (number)
skillCost1if purchasing the service counts against the player’s limit of
learnable professions; otherwise 0 (number)
GetTrainerServiceDescription
Returns the description of a trainer service.
text = GetTrainerServiceDescription(index)
Generally returns the same description found in the spell’s tooltip for spells
purchased from a class trainer; returns nil for trade skills and recipes.
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
Returns:
textDescription of the service (string)
818 Part IV Reference
GetTrainerServiceIcon
Returns the icon for a trainer service.
icon = GetTrainerServiceIcon(index)
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
Returns:
iconPathtoanicontexturefortheservice(string)
GetTrainerServiceInfo
Returns information about an entry in the trainer service listing.
serviceName, serviceSubText, serviceType, isExpanded = i
GetTrainerServiceInfo(index)
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
Returns:
serviceNameName of the service (string)
serviceSubTextSecondary text associated with the service (often a spell
rank; e.g. ‘‘(Rank 4)’’) (string)
serviceTypeType of service entry (string)
availableThe player can currently use this service
headerThis entry is a group header, not a trainer service
unavailableThe player cannot currently use this service
usedThe player has already used this service
isExpanded1if the entry is a header which is currently expanded, or
if the header containing the entry is expanded; otherwise nil (1nil)
GetTrainerServiceItemLink
Returns a hyperlink for the item associated with a trainer service.
link = GetTrainerServiceItemLink(index)
Currently only returns item links for trainer services which teach trade skill
recipes which produce items; does not return spell or recipe links.
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
Returns:
linkA hyperlink for the item associated with a trainer service (string,
hyperlink)
GetTrainerServiceLevelReq
Returns the character level required to purchase a trainer service.
reqLevel = GetTrainerServiceLevelReq(index)
Chapter 27 API Reference 819
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
Returns:
reqLevelLevel required to purchase the service, or nil if the service has no
level requirement (number)
GetTrainerServiceNumAbilityReq
Returns the number of ability requirements for purchasing a trainer service.
numRequirements = GetTrainerServiceNumAbilityReq(index)
Ability requirements are often used for ranked class spells purchased from the
trainer: e.g. learning Blood Strike (Rank 3) requires having learned Blood Strike
(Rank 2). See GetTrainerServiceAbilityReq() for information about
specific ability requirements.
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
Returns:
numRequirementsNumber of different ability requirements for the trainer
service (number)
Example:
-- prints a list of trainer services with their ability requirements
for index = 1, GetNumTrainerServices() do
local name, rank, serviceType = GetTrainerServiceInfo(index)
if serviceType ~= “header“ then
local numRequirements = GetTrainerServiceNumAbilityReq(index)
if numRequirements > 0 then
print(“Ability requirements for “ .. name .. i
“ (“ .. rank .. “):“)
for i=1,numRequirements do
local ability, hasReq = i
GetTrainerServiceAbilityReq(index, i)
if hasReq then
print(“ + “ .. ability)
else
print(“ - “ .. ability)
end
end
end
end
end
GetTrainerServiceSkillLine
Returns the name of the skill line associated with a trainer service.
skillLine = GetTrainerServiceSkillLine(index)
820 Part IV Reference
For trade skill trainers, skill line is the name of the trade skill (e.g. Tailoring,
First Aid). For other trainers, skill line is the name of the group header under
which the skill appears (e.g. Riding, Frost, Protection, Holy, Defense, Dual
Wield).
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
Returns:
skillLineName of the skill line associated with the service (string)
GetTrainerServiceSkillReq
Returns information about the skill requirement for a trainer service.
skill, rank, hasReq = GetTrainerServiceSkillReq(index)
Often used for trade skill recipes: e.g. Netherweave Bag requires
Tailoring (315).
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
Returns:
skillName of the required skill (string)
rankRank required in the skill (number)
hasReq1if the player has the required skill and rank; otherwise nil (1nil)
GetTrainerServiceTypeFilter
Returns whether the trainer service listing is filtered by a service status.
isEnabled = GetTrainerServiceTypeFilter(“type“)
Arguments:
typeA trainer service status (string)
availableServices the player can use
unavailableServices the player cannot currently use
usedServices the player has already used
Returns:
isEnabled1if services matching the filter type are shown in the listing; other-
wise nil (1nil)
GetTrainerSkillLineFilter
Returns whether the trainer service listing is filtered by a skill line.
isEnabled = GetTrainerSkillLineFilter(index)
The default UI does not provide control for skill line filters, but they can
nonetheless be used to alter the contents of the trainer service listing.
Arguments:
indexIndex of a skill line filter (in the list returned by GetTrainer
SkillLines())(number)
Chapter 27 API Reference 821
Returns:
isEnabled1if the given filter is enabled, otherwise nil (1nil)
GetTrainerSkillLines
Returns the list of service group names available at a trainer.
... = GetTrainerSkillLines()
Skill lines as used here correspond to the group headers in the trainer service
listing. Not used for trade skill trainers.
Returns:
...A list of strings, each the localized name of a group in the trainer service
listing (string)
Example:
-- for a paladin interacting with his or her class trainer
GetTrainerSkillLines()
-- returns “Defense“, “Holy“, “Mounts“, “Plate Mail“, “Protection“,
-- “Retribution“
-- when interacting with the Silvermoon weapons master
GetTrainerSkillLines()
-- returns “Polearms“, “Swords“, “Two-Handed Swords“
GetUnitHealthModifier
Returns the health modifier for the player’s pet.
modifier = GetUnitHealthModifier(“unit“)
Arguments:
unitA unit to query; only valid for pet (string,unitID)
Returns:
modifierFactor modifying the unit’s health value (number)
GetUnitHealthRegenRateFromSpirit
Returns the increase in health regeneration rate provided by Spirit.
regen = GetUnitHealthRegenRateFromSpirit(“unit“)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
Returns:
regenIncrease in non-combat health regeneration per second provided by
Spirit (number)
GetUnitManaRegenRateFromSpirit
Returns the increase in mana regeneration rate provided by Spirit.
regen = GetUnitManaRegenRateFromSpirit(“unit“)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
822 Part IV Reference
Returns:
regenIncrease in inactive (non-casting) mana regeneration per second pro-
vided by Spirit (number)
GetUnitMaxHealthModifier
Returns the maximum health modifier for the player’s pet.
modifier = GetUnitMaxHealthModifier(“unit“)
Arguments:
unitA unit to query; only valid for pet (string,unitID)
Returns:
modifierFactor modifying the unit’s maximum health value (number)
Blizzard UI GetUnitName
Returns a string summarizing a unit’s name and server.
nameString = GetUnitName(“unit“, showServerName)
Arguments:
unit—Unit to query (string,unitID)
showServerNameTrue to include the server name in the return
value if the unit is not from the same server as the player; false
to only include a short label in such circumstances (boolean)
Returns:
nameStringThe unit’s name, possibly followed by the name of the unit’s
home server or a label indicating the unit is not from the player’s server (string)
GetUnitPitch
Returns the player’s current pitch (slope or angle of movement).
pitch = GetUnitPitch(“unit“)
Only valid for the unitID ‘‘player’’. The slope returned here reflects only the
direction of movement for swimming or flying, not the current orientation of
the player model or camera. (When on solid ground, GetUnitPitch indicates
what the angle of flight would be were the player to start flying.)
The returned value is in radians, with positive values indicating upward slope,
negative values indicating downward slope, and 0 indicating perfectly level
flight (or swimming).
Arguments:
unitUnit to query; only valid for player (string,unitID)
Returns:
pitchUnit’s slope of movement in radians (number)
GetUnitPowerModifier
Returns the mana modifier for the player’s pet.
modifier = GetUnitPowerModifier(“unit“)
Arguments:
unitA unit to query; only valid for pet (string,unitID)
Chapter 27 API Reference 823
Returns:
modifierFactor modifying the unit’s mana value (number)
GetUnitSpeed
Returns a unit’s current speed.
speed = GetUnitSpeed(unit)
Valid for all observable units. Values returned indicate the current movement
speed in yards per second. (It’s not relative to facing or ground position;
i.e. you won’t see a smaller value when flying up at an angle or a negative
value when backing up.) Does not indicate falling speed or the speed of boats,
zeppelins, and some forms of quest-related transportation, but does indicate
current speed on taxi flights and when moving due to combat effects such as
Disengage, Death Grip, or various knockback abilities.
Examples: Normal running: 7; Walking: 2.5; Running backwards: 4.5; Epic
flying mount: 26.6
Arguments:
unit—Unit to query (unitid)
Returns:
speedUnit’s current speed in yards per second (number)
GetUnspentTalentPoints
Returns the number of unused talent points.
points = GetUnspentTalentPoints(inspect, pet, talentGroup)
Arguments:
inspecttrue to return information for the currently inspected
unit; false to return information for the player (boolean)
pettrue to return information for the player’s pet; false to return informa-
tion for the player (boolean)
talentGroupWhich set of talents to edit, if the player has Dual Talent Special-
ization enabled (number)
1Primary Talents
2—Secondary Talents
nilCurrently active talents
Returns:
pointsNumber of points available for spending (number)
GetVideoCaps
Returns information about graphics capabilities of the current system.
hasAnisotropic, hasPixelShaders, hasVertexShaders, hasTrilinear, i
hasTripleBufering, maxAnisotropy, hasHardwareCursor = GetVideoCaps()
Returns:
hasAnisotropic1if anisotropic filtering is available; otherwise 0 (number)
hasPixelShaders1if pixel shaders are available; otherwise 0 (number)
824 Part IV Reference
hasVertexShaders1if vertex shaders are available; otherwise 0 (number)
hasTrilinear1if trilinear filtering is available; otherwise 0 (number)
hasTripleBufering1if triple buffering is available; otherwise 0 (number)
maxAnisotropyNumber of available settings for anisotropic filtering
(corresponds to the ‘‘Texture Filtering’’ slider in the default UI) (number)
hasHardwareCursor1if hardware cursor support is available; otherwise 0
(number)
GetVoiceCurrentSessionID
Returns an identifier for the active voice session.
id = GetVoiceCurrentSessionID()
Returns:
idIndex of the active voice session (between 1and GetNumVoice
Sessions()), or nil if no session is active (number)
GetVoiceSessionInfo
Returns information about a voice session.
name, active = GetVoiceSessionInfo(session)
Arguments:
sessionIndex of a voice session (between 1and GetNumVoiceSessions())
(number)
Returns:
nameName of the voice session (channel) (string)
active1if the session is the active voice channel; otherwise nil (1nil)
GetVoiceSessionMemberInfoBySessionID
Returns information about a member of a voice channel.
name, voiceActive, sessionActive, muted, squelched = i
GetVoiceSessionMemberInfoBySessionID(session, index)
Arguments:
sessionIndex of a voice session (between 1and GetNumVoiceSessions())
(number)
indexIndex of a member in the voice session (between 1and
GetNumVoiceSessionMembersBySessionID(session))(number)
Returns:
nameName of the member (string)
voiceActive1if the member has enabled voice chat; otherwise nil (1nil)
sessionActive1if the channel is the member’s active voice channel; other-
wise nil (1nil)
muted1if the member is on the player’s muted list; otherwise nil (1nil)
squelched1if the member was silenced by the channel moderator; otherwise
nil (1nil)
Chapter 27 API Reference 825
GetVoiceStatus
Returns whether a character has voice chat enabled.
status = GetVoiceStatus(unit, “channel“) or i
GetVoiceStatus(“name“, “channel“)
Arguments:
unitThe unitid to query (unitid)
nameThe name of the player to query (string)
channelChannel to query for voice status. (string)
Returns:
status1if voice is enabled; otherwise nil (1nil)
GetWatchedFactionInfo
Returns information about the ‘‘watched’’ faction (displayed on the XP bar in
the default UI).
name, standingID, barMin, barMax, barValue = GetWatchedFactionInfo()
Returns:
nameName of the faction being watched (string)
standingIDThe player’s current standing with the faction (number,
standingID)
1—Hated
2Hostile
3—Unfriendly
4—Neutral
5—Friendly
6Honored
7Revered
8—Exalted
barMinThe minimum value for the faction status bar (number)
barMaxThe maximum value for the faction status bar (number)
barValueThe current value for the faction status bar (number)
GetWeaponEnchantInfo
Returns information about temporary enchantments on the player’s weapons.
hasMainHandEnchant, mainHandExpiration, mainHandCharges, i
hasOffHandEnchant, offHandExpiration, offHandCharges = i
GetWeaponEnchantInfo()
Does not return information about permanent enchantments added via
Enchanting, Runeforging, etc; refers instead to temporary buffs such as wizard
oils, sharpening stones, rogue poisons, and shaman weapon enhancements.
Returns:
hasMainHandEnchant1if the main hand weapon has a temporary enchant
(1nil)
mainHandExpirationThe time until the enchant expires, in milliseconds
(number)
mainHandChargesThe number of charges left on the enchantment (number)
hasOffHandEnchant1if the offhand weapon has a temporary enchant (1nil)
826 Part IV Reference
offHandExpirationThe time until the enchant expires, in milliseconds
(number)
offHandChargesThe number of charges left on the enchantment (number)
GetWhoInfo
Returns information about a character in the Who system query results.
name, guild, level, race, class, zone, filename = GetWhoInfo(index)
Arguments:
indexIndex of an entry in the Who system query results (between 1and
GetNumWhoResults())(number)
Returns:
nameName of the character (string)
guildName of the character’s guild (string)
levelLevel of the character (number)
raceLocalized name of the character’s race (string)
classLocalized name of the character’s class (string)
zoneName of the zone in which the character was located when the query
was performed (string)
filenameA non-localized token representing the character’s class (string)
GetWintergraspWaitTime
Returns the amount of time remaining until the next PvP event in the
Wintergrasp zone.
seconds = GetWintergraspWaitTime()
Only accurate while the player is in Northrend; returns nil if the player has
not been in Northrend this session, or the last known value if the player has
been in Northrend this session and is currently elsewhere. Also returns nil if
the Battle for Wintergrasp is in progress.
Returns:
secondsNumber of seconds (rounded to the nearest five) remaining until
the next Battle for Wintergrasp (number)
GetWorldPVPQueueStatus
Returns information on the players queue for a world PvP zone.
status, mapName, queueID = GetWorldPVPQueueStatus(index)
Arguments:
indexIndex of the queue to get data for (between 1and MAX_WORLD_PVP
_QUEUES)(number)
Returns:
statusReturns the status of the players queue (string)
confirmThe player can enter the pvp zone
noneNo world pvp queue at this index
queuedThe player is queued for this pvp zone
Chapter 27 API Reference 827
mapNameMap name they are queued for (e.g Wintergrasp) (string)
queueIDQueue ID, used for BattlefieldMgrExitRequest() and Battlefield
MgrEntryInviteResponse() (number)
Example:
--Prints the players status for their queued non-instanced pvp zones
for index=1, MAX_WORLD_PVP_QUEUES do
local status, mapName = GetWorldPVPQueueStatus(index)
if( status == “queued“ ) then
print(“You are queued for“, mapName)
elseif( status == “confirm“ ) then
print(“Queue is ready, can join“, mapName)
end
end
GetWorldStateUIInfo
Returns information about a world state UI element.
uiType, state, text, icon, dynamicIcon, tooltip, dynamicTooltip, i
extendedUI, extendedUIState1, extendedUIState2, extendedUIState3 = i
GetWorldStateUIInfo(index)
World State UI elements include PvP, instance, and quest objective information
(displayed at the top center of the screen in the default UI) as well as more
specific information for ‘‘control point’’ style PvP objectives. Examples: the
Horde/Alliance score in Arathi Basin, the tower status and capture progress
bars in Hellfire Peninsula, the progress text in the Black Morass and Violet
Hold instances, and the event status text for quests The Light of Dawn and The
Battle For The Undercity.
Arguments:
indexIndex of a world state UI element (between 1and GetNumWorld
StateUI())(number)
Returns:
uiType1if the element should be conditionally displayed (based on
the state of the ‘‘Show World PvP Objectives’’ setting and the player’s
location); any other value if the element is always displayed (number)
stateState of the element: 0 always indicates the element should
be hidden; other possible states vary by context (e.g. in Warsong
Gulch, state 2 indicates the team holds the enemy flag) (number)
textText to be displayed for the element (string)
iconPath to a texture for the element’s main icon (usually describing the ele-
ment itself: e.g. a Horde or Alliance icon for elements displaying a battleground
score) (string)
dynamicIconPath to a texture for a secondary icon (usually describ-
ing transient status: e.g. a flag icon in Warsong Gulch) (string)
tooltipText to be displayed when mousing over the UI element (string)
828 Part IV Reference
dynamicTooltipText to be displayed when mousing over the element’s
dynamicIcon (string)
extendedUIIdentifies the type of additional UI elements to display if
applicable (string)
““No additional UI should be displayed
“CAPTUREPOINT“A capture progress bar should be displayed for the ele-
ment
extendedUIState1Index of the capture progress bar corresponding to the
element (number)
extendedUIState2Position of the capture bar (0 =left/Horde edge, 100 =
right/Alliance edge) (number)
extendedUIState3Width of the neutral section of the capture bar: e.g.
if 50, the extendedUIState2 values 0-25 correspond to Horde ownership
of the objective, values 76-100 to Alliance ownership, and values 26-75 to no
ownership (number)
GetXPExhaustion
Returns the amount of rested bonus experience available.
exhaustionXP = GetXPExhaustion()
This value increments as the player spends time resting and depletes as the
player earns experience from kills while rested.
Returns:
exhaustionXPThe amount of rested bonus experience available (number)
GetZonePVPInfo
Returns PVP information about the current area.
pvpType, isSubZonePVP, factionName = GetZonePVPInfo()
Information returned may apply to the current subzone, not the entire zone.
Returns:
pvpTypePvP status for the area (string)
arenaArena or outdoor free-for-all area (e.g. Gurubashi Arena)
combatCombat zone (e.g. Wintergrasp)
contestedHorde/Alliance PvP is enabled for all players
friendlyZone is controlled by the player’s faction; PvP status
is optional for the player but mandatory for enemy players
hostileZone is controlled by the enemy’s faction; PvP sta-
tus is optional for the enemy but mandatory for the player
nilPvP status is not automatically enabled for either faction (used for
‘‘contested’’ zones on Normal servers)
sanctuaryPvP activity is not allowed (e.g. Dalaran)
isSubZonePVP1if the current area allows free-for-all PVP; otherwise nil
(1nil)
Chapter 27 API Reference 829
factionNameName of the faction that controls the zone (only applies if
pvpType is friendly or hostile) (string)
GetZoneText
Returns the name of the zone in which the player is located.
zone = GetZoneText()
Returns:
zoneName of the current zone (string)
GiveMasterLoot
Awardsalootitemtoagroupmember.
GiveMasterLoot(slot, index)
Has no effect if the player is not the loot master or if no loot or candidate
matching the given parameters exists.
Arguments:
slotIndex of a loot slot (between 1and GetNumLootItems())(number)
indexIndex of a loot candidate (see GetMasterLootCandidate())(number)
GlyphMatchesSocket
Returns whether a socket is eligible for the glyph currently awaiting a target.
match = GlyphMatchesSocket(socket)
Only valid during glyph application: when the player has activated the glyph
item but before she has chosen the glyph slot to put it in (i.e. the glowing hand
cursor is showing).
Arguments:
socketWhich glyph socket to query (between 1and NUM_GLYPH_SLOTS)
(number,glyphIndex)
Returns:
match1if the glyph awaiting a target fits the given socket; nil if it doesn’t fit
or if no glyph is awaiting a target (1nil)
GrantLevel
Grants a level to the player’s Recruit-a-Friend partner.
GrantLevel(“unit“)
Does not immediately cause the partner character to level up: that player is
given a chance to accept or decline the offered level.
Arguments:
unitUnit to gift a level (string,unitID)
GuildControlAddRank
Adds a new rank to the player’s guild.
GuildControlAddRank(“name“)
The newly added rank becomes the lowest rank in the guild.
830 Part IV Reference
Arguments:
nameName of the new rank (string)
GuildControlDelRank
Deletes a guild rank.
GuildControlDelRank(“name“)
Arguments:
nameName of the rank to delete (string)
GuildControlGetNumRanks
Returns the number of ranks in the guild.
numRanks = GuildControlGetNumRanks()
Returns:
numRanksNumber of guild ranks (including Guild Leader) (number)
GuildControlGetRankFlags
Returns the list of privileges for the guild rank being edited.
... = GuildControlGetRankFlags()
The name of a privilege for an index in this list can be found in the global
variable “GUILDCONTROL_OPTION“..index.
Returns:
...A list of privilege flags (1=privilege allowed, nil =privilege denied) for
the rank being edited (list)
Example:
-- Print rank flags for the first rank in the guild
function PrintFlags(...)
local output = ““
for i = 1, select(“#“, ...) do
output = output .. getglobal(“GUILDCONTROL_OPTION“..i) .. i
“: “ .. select(i, ...) .. “; “
end
print(output)
end
GuildControlSetRank(1)
PrintFlags(GuildControlGetRankFlags())
GuildControlGetRankName
Returns the name of a guild rank.
rankName = GuildControlGetRankName(rank)
Arguments:
rankIndex of a rank to edit (between 1and GuildControlGetNumRanks())
(number)
Returns:
rankNameName of the guild rank (string)
Chapter 27 API Reference 831
GuildControlSaveRank
Saves changes to the guild rank being edited.
GuildControlSaveRank(“name“)
Arguments:
nameNew name for the guild rank (string)
GuildControlSetRank
Chooses a guild rank to edit.
GuildControlSetRank(rank)
Arguments:
rankIndex of a rank to edit (between 1and GuildControlGetNumRanks())
(number)
GuildControlSetRankFlag
Enables or disables a privilege for the guild rank being edited.
GuildControlSetRankFlag(index, enabled)
Changes are not saved until a call is made to GuildControlSaveRank().
Arguments:
indexIndex of a privilege to change (number)
1Guildchat listen
2Guildchat speak
3Officerchat listen
4—Ofcerchat speak
5—Promote
6—Demote
7—Invite Member
8Remove Member
9—Set MOTD
10Edit Public Notes
11—View Ofcer Note
12Edit Officer Note
13Modify Guild Info
15Use guild funds for repairs
16Withdraw gold from the guild bank
17Create Guild Event
enabledTrue to allow the privilege; false to deny (boolean)
GuildDemote
Reduces a guild member’s rank by one.
GuildDemote(“name“)
The player can only demote members whose rank is below the player’s own,
and only if the player has permission to demote (i.e. if CanGuildDemote()
returns 1).
Arguments:
nameName of a guild member to demote (string)
Confirmation GuildDisband
Disbands the player’s guild. Only has effect if the player is the guild leader.
832 Part IV Reference
GuildInfo
Requests guild information from the server.
Fires two CHAT_MSG_SYSTEM events, one containing the name of the guild,
followed by one containing the date the guild was created and how many
players and accounts belong to the guild.
GuildInvite
Invites a character to join the player’s guild.
GuildInvite(“name“)
Arguments:
nameName of a character to invite (string)
Confirmation GuildLeave
Leaves the player’s current guild.
GuildPromote
Increases a guild member’s rank by one.
GuildPromote(“name“)
The player can only promote members up to the rank immediately below the
player’s own, and only if the player has permission to promote (i.e. if
CanGuildPromote() returns 1).
Arguments:
nameName of a guild member to promote (string)
GuildRoster
Requests guild roster information from the server.
Information is not returned immediately; the GUILD_ROSTER_UPDATE event
fires when data is available for retrieval via GetGuildRosterInfo() and
related functions. Requests are throttled to reduce server load; the server will
only respond to a new request approximately 10 seconds after a previous
request.
GuildRosterSetOfficerNote
Sets the officer note for a guild member.
GuildRosterSetOfficerNote(index, “note“)
Arguments:
indexIndex of a member in the guild roster (between 1and
GetNumGuildMembers()), or 0 for no selection (number)
noteNote text to set for the guild member (up to 31 characters) (string)
GuildRosterSetPublicNote
Sets the public note for a guild member.
GuildRosterSetPublicNote(index, “note“)
Arguments:
indexIndex of a member in the guild roster (between 1and GetNum
GuildMembers()), or 0 for no selection (number)
noteNote text to set for the guild member (up to 31 characters) (string)
Chapter 27 API Reference 833
GuildSetLeader
Promotes a member to guild leader.
GuildSetLeader(“name“)
Only works if the player is the guild leader and the named character is in the
guild and currently online.
Arguments:
nameName of a guild member to promote to leader (string)
GuildSetMOTD
Sets the guild Message of the Day.
GuildSetMOTD(“message“)
Guild members see the message of the day upon login and whenever it is
changed (and cannot disable its display in the default UI), so keeping the
message concise is recommended.
Arguments:
messageNew text for the message of the day (up to 128 characters; embedded
newlines allowed) (string)
Example:
-- Set a message of the day
GuildSetMOTD(“This is a message of the day“)
-- Set a two-line message of the day
GuildSetMOTD(“Please vote for the following applicants on our i
forums:\nCladhaire\nCairthas“)
GuildUninvite
Removes a character from the player’s guild.
GuildUninvite(“name“)
Arguments:
nameName of a guild member to remove (string)
HasAction
Returns whether an action slot contains an action.
hasAction = HasAction(slot)
Arguments:
slotAn action bar slot (number,actionID)
Returns:
hasAction1if the slot contains an action; otherwise nil (1nil)
HasFilledPetition
Returns whether the player has a completed petition.
hasPetition = HasFilledPetition()
834 Part IV Reference
Used by the default UI to show and hide the buttons for turning in an Arena
charter.
Returns:
hasPetition1if the player has a completed petition; otherwise nil (1nil)
HasFullControl
Returns whether the player character can be controlled.
hasControl = HasFullControl()
Returns:
hasControl1if the player character can be controlled (i.e. isn’t feared,
charmed, etc); otherwise nil (1nil)
HasInspectHonorData
Returns whether PvP honor and arena data for the currently inspected unit has
been downloaded from the server.
hasData = HasInspectHonorData()
See RequestInspectHonorData() to request PvP data from the server.
Returns:
hasData1if the client has PvP data for the currently inspected player; other-
wise nil (1nil)
HasKey
Returns whether the player has any keys stored in the Keyring container.
hasKey = HasKey()
Used in the default UI to show or hide the UI for the Keyring container
Returns:
hasKey—Returns 1if the player has any keys stored in the Keyring container;
otherwise nil (1nil)
HasNewMail
Returns whether the player has received new mail since last visiting a mailbox.
hasMail = HasNewMail()
Returns:
hasMail1if the player has received new mail since last visiting a mailbox;
otherwise nil (1nil)
HasPetSpells
Returns whether the player’s current pet has a spellbook.
hasPetSpells, petType = HasPetSpells()
Returns:
hasPetSpells1if the player currently has an active pet with spells/abilities;
otherwise nil (1nil)
petTypeNon-localized token identifying the type of pet (string)
DEMONA warlock’s demonic minion
PETA hunter’s beast
Chapter 27 API Reference 835
HasPetUI
Returns whether the pet UI should be displayed for the player’s pet.
hasPetUI, isHunterPet = HasPetUI()
Special quest-related pets, vehicles, and possessed units all count as pets but
do not use the pet UI or associated functions.
Returns:
hasPetUI1if the pet UI should be displayed for the player’s pet (1nil)
isHunterPet1if the player’s pet is a hunter pet (1nil)
HasSoulstone
Returns whether the player can instantly resurrect in place.
text = HasSoulstone()
Only returns valid information while the player is dead and has not yet
released his or her spirit to the graveyard.
Returns:
textIf the player can resurrect in place, the text to be displayed on the dialog
button for such (e.g. ‘‘Use Soulstone’’, ‘‘Reincarnate’’); otherwise nil (string)
HasWandEquipped
Returns whether the player has a wand equipped.
isEquipped = HasWandEquipped()
Returns:
isEquipped1if a wand is equipped; otherwise nil (1nil)
HearthAndResurrectFromArea
Instantly exits the current world PvP zone, returning to the player’s
Hearthstone location.
Resets the player’s Hearthstone cooldown, and also returns the player to life if
dead. Only usable if the player is in a world PvP combat zone
(i.e. Wintergrasp).
HideRepairCursor
Returns the cursor to normal mode after use of ShowRepairCursor().
InCinematic
Returns whether an in-game cinematic is playing.
inCinematic = InCinematic()
Applies to in-game-engine cinematics (such as when logging into a new
character for the first time), not prerecorded movies.
Returns:
inCinematic1if an in-game cinematic is playing; otherwise nil (1nil)
InCombatLockdown
Returns whether the user interface is protected due to combat.
inLockdown = InCombatLockdown()
836 Part IV Reference
Non-Blizzard code is allowed to perform certain UI actions (such as changing
secure template attributes or moving/showing/hiding secure frames) only if
the player is not in combat; this function can be used to determine whether
such actions are currently available.
Returns:
inLockdown1if the user interface is protected due to combat; otherwise nil
(1nil)
InRepairMode
Returns whether the item repair cursor mode is currently active.
inRepair = InRepairMode()
Repair mode is entered by calling ShowRepairCursor() and exited by calling
HideRepairCursor(); while in repair mode, calling PickupContainer
Item() or PickupInventoryItem() will attempt to repair the item (and
deduct the cost of such from the player’s savings) instead of putting it on the
cursor.
Returns:
inRepair1if repair mode is currently active; otherwise nil (1nil)
InboxItemCanDelete
Returns whether a message in the player’s inbox can be deleted.
canDelete = InboxItemCanDelete(mailID)
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
Returns:
canDelete1if the message can be deleted; otherwise nil (1nil)
InitiateTrade
Offers to trade with a given unit.
InitiateTrade(“unit“) or InitiateTrade(“name“)
The trade process does not begin immediately; once the server has determined
both clients can trade, the TRADE_SHOW event fires.
Arguments:
unitA unit with which to trade (string,unitID)
nameThe name of a unit with which to trade; only valid for nearby units in the
player’s party/raid (string)
Protected InteractUnit
Interacts with (as with right-clicking on) a unit.
InteractUnit(unit)
Arguments:
unitThe unit to interact with (unitid)
Chapter 27 API Reference 837
Blizzard UI InterfaceOptionsFrame_OpenToCategory
Opens the Interface Options window and displays a given panel within it.
InterfaceOptionsFrame_OpenToCategory(“panelName“) or i
InterfaceOptionsFrame_OpenToCategory(panel)
Arguments:
panelNameThe registered name of an options panel (string)
panelA Frame object already registered as an options panel (table)
Blizzard UI InterfaceOptions_AddCategory
Registers a panel to be displayed in the Interface Options window.
InterfaceOptions_AddCategory(panel)
The following members and methods are used by the Interface Options frame
to display and organize panels:
panel.name -string (required)The name of the AddOn or group of con-
figuration options. This is the text that will display in the AddOn options list.
panel.parent -string (optional)Name of the parent of the
AddOn or group of configuration options. This identifies ‘‘panel’’
as the child of another category. If the parent category doesn’t
exist, ‘‘panel’’ will be displayed as a regular category.
panel.okay -function (optional)This method will run
when the player clicks ‘‘okay’’ in the Interface Options.
panel.cancel -function (optional)This method will run when the
player clicks ‘‘cancel’’ in the Interface Options. Use this to revert their
changes.
panel.default -function (optional)This method will run when the
player clicks ‘‘defaults’’. Use this to revert their changes to your defaults.
panel.refresh -function (optional)This method will run when
the Interface Options frame calls its OnShow function and after defaults
have been applied via the panel.default method described above. Use this
to refresh your panel’s UI in case settings were changed without player
interaction.
Arguments:
panel—A Frame object (table)
InviteUnit
Invites a character to the player’s party or raid.
InviteUnit(“name“)
Arguments:
nameName of a character to invite (string)
IsActionInRange
Returns whether the player’s target is in range of an action.
inRange = IsActionInRange(slot)
838 Part IV Reference
Arguments:
slotAn action bar slot (number,actionID)
Returns:
inRange1if the player’s target is in range for the action or 0 if out of
range; nil if the action cannot be used on the player’s target regardless of range
(number)
IsActiveBattlefieldArena
Returns whether the player is currently in an arena match.
isArena, isRegistered = IsActiveBattlefieldArena()
Returns:
isArena1if player is in an Arena match; otherwise nil (1nil)
isRegistered1if the current arena match is a ranked match; otherwise nil
(1nil)
IsActiveQuestTrivial
Returns whether a quest which can be turned in to the current Quest NPC is
trivial at the player’s level.
trivial = IsActiveQuestTrivial(index)
Only returns valid information after a QUEST_GREETING event. Used in the
default UI to display ‘‘(low level)’’ when listing the quest.
Note: Most quest NPCs present active quests using the GetGossipActive
Quests() instead of this function.
Arguments:
indexIndex of a quest which can be turned in to the current
Quest NPC (between 1and GetNumActiveQuests())(number)
Returns:
trivial1if the quest is trivial at the player’s level; otherwise nil (1nil)
IsAddOnLoadOnDemand
Returns whether an addon can be loaded without restarting the UI.
isLod = IsAddOnLoadOnDemand(“name“) or IsAddOnLoadOnDemand(index)
Arguments:
nameName of an addon (name of the addon’s folder and TOC file, not the Title
found in the TOC) (string)
indexIndex of an addon in the addon list (between 1and GetNumAddOns())
(number)
Returns:
isLod1if the addon is LoadOnDemand-capable; otherwise nil (1nil)
IsAddOnLoaded
Returns whether an addon is currently loaded.
loaded = IsAddOnLoaded(“name“) or IsAddOnLoaded(index)
Chapter 27 API Reference 839
Arguments:
nameName of an addon (name of the addon’s folder and TOC file, not the Title
found in the TOC) (string)
indexIndex of an addon in the addon list (between 1and GetNumAddOns())
(number)
Returns:
loaded1if the addon is loaded; otherwise nil (1nil)
IsAltKeyDown
Returns whether an Alt key on the keyboard is held down.
isDown = IsAltKeyDown()
Returns:
isDown1if an Alt key on the keyboard is currently held down; otherwise nil
(1nil)
IsArenaTeamCaptain
Returns whether the player is the captain of an arena team.
isCaptain = IsArenaTeamCaptain(team)
Also returns 1 if the player is not on a team of the given arenaTeamID.
Arguments:
teamIndex of one of the player’s arena teams (number,arenaTeamID)
Returns:
isCaptain1if the player is the captain of the given team; otherwise nil.
(1nil)
IsAtStableMaster
Returns whether the player is interacting with a Stable Master NPC.
isAtNPC = IsAtStableMaster()
The Pet Stable UI/API can be active without an NPC if the player is using the
Call Stabled Pet ability. New stable slots can only be purchased while talking
to an NPC. The default UI uses this function to determine whether to show
UI elements related to purchasing slots.
Returns:
isAtNPCTrue if the player is interacting with a Stable Master NPC; otherwise
false (boolean)
IsAttackAction
Returns whether an action is the standard melee Attack action.
isAttack = IsAttackAction(slot)
Used in the default UI to flash the action button while auto-attack is active.
Does not apply to other repeating actions such as Auto Shot (for hunters) and
Shoot (for wand users); for those, see IsAutoRepeatAction.
840 Part IV Reference
Arguments:
slotAn action bar slot (number,actionID)
Returns:
isAttack1if the action enables/disables melee auto-attack; otherwise nil
(1nil)
IsAttackSpell
Returns whether a spell is the standard melee Attack spell.
isAttack = IsAttackSpell(index, “bookType“) or IsAttackSpell(“name“)
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
Returns:
isAttack1if the spell enables/disables melee auto-attack; otherwise nil
(1nil)
IsAutoRepeatAction
Returns whether an action is an automatically repeating action.
isRepeating = IsAutoRepeatAction(slot)
Used in the default UI to flash the action button while the action is repeating.
Applies to actions such as Auto Shot (for hunters) and Shoot (for wand and
other ranged weapon users) but not to the standard melee Attack action; for it,
see IsAttackAction.
Arguments:
slotAn action bar slot (number,actionID)
Returns:
isRepeating1if the action is an auto-repeat action; otherwise nil (1nil)
IsAutoRepeatSpell
Returns whether a spell is an automatically repeating spell.
isAutoRepeat = IsAutoRepeatSpell(“spellName“)
Arguments:
spellNameThe name of the spell to query (string)
Returns:
isAutoRepeatIf the spell is an auto-repeating spell (1nil)
IsAvailableQuestTrivial
Returns whether a quest available from the current Quest NPC is trivial at the
player’s level.
trivial = IsAvailableQuestTrivial(index)
Chapter 27 API Reference 841
Only returns valid information after a QUEST_GREETING event. Used in the
default UI to display ‘‘(low level)’’ when listing the quest.
Note: Most quest NPCs present available quests using the GetGossip
AvailableQuests() instead of this function.
Arguments:
indexIndex of a quest available from the current Quest NPC (between 1and
GetNumAvailableQuests())(number)
Returns:
trivial1if the quest is trivial at the player’s level; otherwise nil (1nil)
IsBattlefieldArena
Returns whether the player is interacting with an entity that allows queueing
for arena matches.
isArena = IsBattlefieldArena()
The Battlefield queueing APIs are used for joining arena matches or skirmishes
as well as for battlegrounds; this function is used in the default UI to change
the contents of the queue dialog based on whether arena or battleground
queue options should be presented.
Returns:
isArena1if interacting with an arena queue; otherwise nil (1nil)
IsConsumableAction
Returns whether using an action consumes an item.
isConsumable = IsConsumableAction(slot)
Applies both to consumable items (such as food and potions) and to spells
which use a reagent (e.g. Prayer of Fortitude, Divine Intervention, Water
Walking, Portal: Dalaran).
Arguments:
slotAn action bar slot (number,actionID)
Returns:
isConsumable1if using the action consumes an item; otherwise nil (1nil)
IsConsumableItem
Returns whether an item is consumable.
consumable = IsConsumableItem(itemID) or IsConsumableItem(“itemName“) i
or IsConsumableItem(“itemLink“)
Indicates whether the item is destroyed upon use, not necessarily whether it
belongs to the ‘‘Consumable’’ type/class.
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
842 Part IV Reference
Returns:
consumable1if the item is consumable; otherwise nil (1nil)
IsConsumableSpell
Returns whether casting a spell consumes a reagent item.
isConsumable = IsConsumableSpell(index, “bookType“) or i
IsConsumableSpell(“name“)
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
Returns:
isConsumable1if casting the spell consumes a reagent item; otherwise nil
(1nil)
IsControlKeyDown
Returns whether a Control key on the keyboard is held down.
isDown = IsControlKeyDown()
Returns:
isDown1if a Control key on the keyboard is currently held down; otherwise
nil (1nil)
IsCurrentAction
Returns whether an action is currently being used.
isCurrent = IsCurrentAction(slot)
Arguments:
slotAn action bar slot (number,actionID)
Returns:
isCurrent1if the action is currently being cast, is waiting for the user to
choose a target, is a repeating action which is currently repeating, or is the open
trade skill; otherwise nil (1nil)
IsCurrentItem
Returns whether an item is being used.
isItem = IsCurrentItem(itemID) or IsCurrentItem(“itemName“) or i
IsCurrentItem(“itemLink“)
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Chapter 27 API Reference 843
Returns:
isItem1if the item’s ‘‘Use:’’ action is currently being cast, is waiting for the
user to choose a target, or is otherwise in progress; otherwise nil (1nil)
IsCurrentQuestFailed
Returns whether the player has failed the selected quest in the quest log.
isFailed = IsCurrentQuestFailed()
Returns:
isFailed1if the player has failed the quest; otherwise nil (1nil)
IsCurrentSpell
Returns whether a spell is currently being used.
isCurrent = IsCurrentSpell(index, “bookType“) or IsCurrentSpell(“name“)
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
Returns:
isCurrent1if the spell is currently being cast, is waiting for the user to
choose a target, is a repeating spell which is currently repeating, or is the open
trade skill; otherwise nil (1nil)
IsDesaturateSupported
Returns whether the current hardware supports desaturated textures.
isSupported = IsDesaturateSupported()
Returns:
isSupported1if texture desaturation is supported; otherwise nil (1nil)
IsDisplayChannelModerator
Returns whether the player is a moderator of the selected channel in the
channel list display.
isModerator = IsDisplayChannelModerator()
Returns:
isModerator1if the player is a moderator of the selected channel; otherwise
nil (1nil)
IsDisplayChannelOwner
Returns whether the player is the owner of the selected channel in the channel
list display.
isOwner = IsDisplayChannelOwner()
Returns:
isOwner1if the player is the owner of the selected channel; otherwise nil
(1nil)
844 Part IV Reference
IsDressableItem
Returns whether an item’s appearance can be previewed using the Dressing
Room feature.
isDressable = IsDressableItem(itemID) or i
IsDressableItem(“itemName“) or IsDressableItem(“itemLink“)
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Returns:
isDressable1if the item’s appearance can be previewed using the Dressing
Room feature; otherwise nil (1nil)
IsEquippableItem
Returns whether an item can be equipped.
isEquippable = IsEquippableItem(itemID) or i
IsEquippableItem(“itemName“) or IsEquippableItem(“itemLink“)
Indicates whether an item is capable of being equipped on a character, not
necessarily whether the player character is able to wear it.
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Returns:
isEquippable1if the item can be equipped, otherwise nil (1nil)
IsEquippedAction
Returns whether an action contains an equipped item.
isEquipped = IsEquippedAction(slot)
Applies to actions involving equippable items (not to consumables or other
items with ‘‘Use:’’ effects) and indicates the effect of performing the action: if
an action’s item is not equipped, using the action will equip it; if the item is
equipped and has a ‘‘Use:’’ effect, using the action will activate said effect.
Arguments:
slotAn action bar slot (number,actionID)
Returns:
isEquipped1if the action contains an equipped item; otherwise nil (1nil)
IsEquippedItem
Returns whether an item is currently equipped.
isEquipped = IsEquippedItem(itemID) or i
IsEquippedItem(“itemName“) or IsEquippedItem(“itemLink“)
Chapter 27 API Reference 845
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Returns:
isEquipped1if the item is equipped on the player character; otherwise nil
(1nil)
Example:
-- Check to see if your Alliance PvP trinket is equipped
IsEquippedItem(“Medallion of the Alliance“) then
print(“Your PvP trinket is already equipped.“)
else
print(“*** Make sure to equip your PvP trinket ***“)
end
-- Check to see if Staff of Infinite Mysteries (itemId 28633)
-- is equipped
if IsEquippedItem(28633) then
print(“Your staff is equipped“)
else
print(“Your staff is not equipped“)
end
IsEquippedItemType
Returns whether any items of a given type are currently equipped.
isEquipped = IsEquippedItemType(“type“)
Possible arguments include the localized names of item classes (as returned
from GetAuctionItemClasses; e.g. ‘‘Weapon’’, ‘‘Armor’’), subclasses (as
returned from GetAuctionItemSubClasses; e.g. ‘‘One-handed axes’’,
‘‘Shields’’, ‘‘Cloth’’), and the global tokens or localized names for equip
locations (as returned from GetAuctionInvTypes; e.g. ‘‘INVTYPE_WEAPON
MAINHAND’’, ‘‘Off Hand’’).
Arguments:
typeName of an item class, subclass, or equip location (string)
Returns:
isEquipped1if the player has equipped any items of the given type; other-
wise nil (1nil)
Example:
-- Check to see if the player currently has a shield equipped
local hasShield = IsEquippedItemType(“Shields“)
if hasShield then
print(“You currently have a shield equipped“)
else
print(“You do not have a shield equipped“)
end
846 Part IV Reference
IsFactionInactive
Returns whether a faction is flagged as ‘‘inactive’’.
isInactive = IsFactionInactive(index)
‘‘Inactive’’ factions behave no differently; the distinction only exists to allow
players to hide factions they don’t care about from the main display. Factions
thus marked are automatically moved to an ‘‘Inactive’’ group at the end of the
faction list.
Arguments:
indexIndex of an entry in the faction list; between 1and GetNumFactions()
(number)
Returns:
isInactive1if the faction is currently flagged as ‘‘inactive’’; otherwise nil
(1nil)
IsFalling
Returns whether the player is currently falling.
falling = IsFalling()
Returns:
falling1if the player is falling; otherwise nil (1nil)
IsFishingLoot
Returns whether the currently displayed loot came from fishing.
isFishing = IsFishingLoot()
Used in the default UI to play a fishing sound effect and change the
appearance of the loot window.
Returns:
isFishing1if the currently displayed loot is fishing loot; otherwise nil
(1nil)
IsFlyableArea
Returns whether flight is allowed on the continent where the player is
currently located.
isFlyable = IsFlyableArea()
Returns 1 for some areas in which flight is disablednotably Dalaran (with
the exception of the Krasus’ Landing subzone) and Wintergrasp.
Returns:
isFlyable1if flight is allowed on the continent where the player is currently
located; otherwise nil (1nil)
IsFlying
Returns whether the player is currently flying.
isFlying = IsFlying()
Returns:
isFlying1if the player is currently flying; otherwise nil (1nil)
Chapter 27 API Reference 847
IsGuildLeader
Returns whether or player is leader of his or her guild.
isLeader = IsGuildLeader()
Returns:
isLeader1if the player is a guild leader; otherwise nil (1nil)
IsHarmfulItem
Returns whether an item can be used against hostile units.
isHarmful = IsHarmfulItem(itemID) or IsHarmfulItem(“itemName“) or i
IsHarmfulItem(“itemLink“)
Harmful items include grenades and various quest items (‘‘Use this to zap 30
murlocs!’’).
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Returns:
isHarmful1if the item can be used against hostile units; otherwise nil
(1nil)
IsHarmfulSpell
Returns whether a spell can be used against hostile units.
isHarmful = IsHarmfulSpell(index, “bookType“) or IsHarmfulSpell(“name“)
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
Returns:
isHarmful1if the spell can be used against hostile units; otherwise nil
(1nil)
Example:
-- print a list of harmful spells
local numTabs = GetNumSpellTabs()
for i=1,numTabs do
local name,texture,offset,numSpells = GetSpellTabInfo(i)
for spellId=1,numSpells do
local harmful = IsHarmfulSpell(i, “spell“)
if harmful then
local name,rank = GetSpellName(i, “spell“)
848 Part IV Reference
print(name .. “ is a harmful spell“)
end
end
end
IsHelpfulItem
Returns whether an item can be used on the player or friendly units.
isHarmful = IsHelpfulItem(itemID) or IsHelpfulItem(“itemName“) or i
IsHelpfulItem(“itemLink“)
Helpful items include potions, scrolls, food and drink.
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Returns:
isHarmful1if the item can be used on the player or friendly units; otherwise
nil (1nil)
IsHelpfulSpell
Returns whether an item can be used on the player or friendly units.
isHarmful = IsHelpfulSpell(index, “bookType“) or IsHelpfulSpell(“name“)
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
Returns:
isHarmful1if the spell can be used on the player or friendly units; otherwise
nil (1nil)
IsIgnored
Returns whether a unit is on the player’s ignore list.
isIgnored = IsIgnored(“unit“) or IsIgnored(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query (string)
Returns:
isIgnored1if the unit is on the player’s ignore list; otherwise nil (1nil)
IsIgnoredOrMuted
Returns whether a unit can be heard due to ignored/muted status.
isIgnoredOrMuted = IsIgnoredOrMuted(“unit“)
Chapter 27 API Reference 849
Arguments:
unit—A unit to query (string,unitID)
Returns:
isIgnoredOrMuted1if the unit is ignored or muted, nil otherwise (1nil)
IsInArenaTeam
Returns whether the player is on an arena team.
isInTeam = IsInArenaTeam()
Returns:
isInTeamTrue if the player is on any arena teams; false otherwise
(boolean)
IsInGuild
Returns whether the player is in a guild.
inGuild = IsInGuild()
Returns:
inGuild1if the player is in a guild; otherwise nil (1nil)
IsInInstance
Returns whether the player is in an instance (and its type if applicable).
isInstance, instanceType = IsInInstance()
Returns:
isInstance1if the player is in an instance, otherwise nil (1nil)
instanceTypeThe type of instance the player is in (string)
arenaPlayer versus player arena
noneNot inside an instance
party5-man instance
pvpPlayer versus player battleground
raidRaid instance
IsInLFGQueue
Returns whether the player is currently queued for automatically
joining/filling a group.
inQueue = IsInLFGQueue()
Returns:
inQueue1if the player is currently queued for automatically joining/filling a
group; otherwise nil (1nil)
IsIndoors
Returns whether the player is currently indoors.
inside = IsIndoors()
Returns:
inside1if the player is currently indoors; otherwise nil (1nil)
850 Part IV Reference
IsInventoryItemLocked
Returns whether an inventory slot is locked.
isLocked = IsInventoryItemLocked(slot)
Items become locked while being moved, split, or placed into other UI
elements (such as the mail, trade, and auction windows); the item is unlocked
once such an action is completed.
Arguments:
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
Returns:
isLocked1if the item in the inventory slot is locked; otherwise nil (1nil)
IsItemInRange
Returns whether the player is in range to use an item on a unit.
inRange = IsItemInRange(itemID, “unit“) or i
IsItemInRange(“itemName“, “unit“) or IsItemInRange(“itemLink“, “unit“)
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
unitA unit on which to use the item (string,unitID)
Returns:
inRange1if the player is near enough to use the item on the unit; 0 if
not in range; nil if the unit is not a valid target for the item (1nil)
IsLeftAltKeyDown
Returns whether the left Alt key is currently held down.
isDown = IsLeftAltKeyDown()
(Note: The Mac WoW client does not distingish between left and right modifier
keys, so both Alt keys are reported as Left Alt.)
Returns:
isDown1if the left Alt key on the keyboard is currently held down; otherwise
nil (1nil)
IsLeftControlKeyDown
Returns whether the left Control key is held down.
isDown = IsLeftControlKeyDown()
(Note: The Mac WoW client does not distingish between left and right modifier
keys, so both Control keys are reported as Left Control.)
Returns:
isDown1if the left Control key is held down; otherwise nil (1nil)
Chapter 27 API Reference 851
IsLeftShiftKeyDown
Returns whether the left Shift key on the keyboard is held down.
isDown = IsLeftShiftKeyDown()
(Note: The Mac WoW client does not distingish between left and right modifier
keys, so both Shift keys are reported as Left Shift.)
Returns:
isDown1if the left Shift key on the keyboard is currently held down; other-
wise nil (1nil)
IsLinuxClient
Returns whether the player is using the Linux game client.
isLinux = IsLinuxClient()
Does not indicate whether the player is running a Windows client on Linux
with virtualization software. Blizzard has not released an official WoW client
for Linux, but this function is included just in case that situation changes.
Returns:
isLinux1if running the Linux client; otherwise nil (1nil)
IsLoggedIn
Returns whether the login process has completed.
loggedIn = IsLoggedIn()
The PLAYER_LOGIN event provides similar information; this function presents
an alternative that can be used across UI reloads.
Returns:
loggedIn1if the login process has completed; otherwise nil (1nil)
IsMacClient
Returns whether the player is using the Mac OS X game client.
isMac = IsMacClient()
Returns:
isMac1if running the Mac OS X client; otherwise nil (1nil)
IsModifiedClick
Determines if the modifiers specified in the click-type had been held down
while the button click occurred.
modifiedClick = IsModifiedClick(“type“)
If called from a click handler (OnMouseDown,OnMouseUp,OnClick,
OnDoubleClick,PreClick,orPostClick), checks mouse buttons included in
the binding; otherwise checks modifiers only (see example).
Arguments:
typeToken identifying a modified click action (string)
852 Part IV Reference
Returns:
modifiedClick1if the modifier key set bound to the action
is active (i.e. the keys are held down); otherwise nil (1nil)
Example:
print(GetModifiedClick(“CHATLINK“))
-- shows “SHIFT-BUTTON1“ by default
-- creates a button to respond to the CHATLINK action
TestFrame = CreateFrame(“Button“, “TestFrame“, UIParent, i
“UIPanelButtonTemplate“)
TestFrame:SetWidth(100)
TestFrame:SetHeight(24)
TestFrame:SetPoint(“CENTER“, 0, -30)
TestFrame:RegisterForClicks(“AnyUp“)
TestFrame:SetScript(“OnEnter“, function(self) i
print(IsModifiedClick(“CHATLINK“) and “true on enter“ or i
“false on enter“) end)
TestFrame:SetScript(“OnClick“, function(self) i
print(IsModifiedClick(“CHATLINK“) and “true on click“ or i
“false on click“) end)
-- prints “true on enter“ if the Shift key is held while mousing
-- over the button, regardless of mouse button state
-- prints “false on enter“ if not holding Shift
-- prints “true on click“ only if the button is activated by clicking
-- the primary (left) mouse button while holding the Shift key
-- prints “false on click“ if activated by any other mouse button
-- or combination of modifier keys
IsModifierKeyDown
Returns whether a modifier key is held down.
isDown = IsModifierKeyDown()
Modifier keys include Shift, Ctrl, or Alt on either side of the keyboard. WoW
does not recognize platform-specific modifier keys (such as fn, meta, Windows,
or Command).
Returns:
isDown1if any modifier key is held down; otherwise nil (1nil)
IsMounted
Returns whether the player is mounted.
mounted = IsMounted()
Returns:
mounted1if the player character is riding a summoned mount; otherwise nil
(1nil)
IsMouseButtonDown
Returns whether a given mouse button is held down.
isDown = IsMouseButtonDown([button])
Chapter 27 API Reference 853
If no button is specified, returns 1 if any mouse button is held down.
Arguments:
button (optional)Number or name of a mouse button (number,string)
1 or LeftButtonPrimary mouse button
2 or RightButtonSecondary mouse button
3 or MiddleButtonThird mouse button (or clickable scroll control)
4 or Button4Fourth mouse button
5 or Button5Fifth mouse button
Returns:
isDown1if the mouse button is down; otherwise nil (1nil)
IsMouselooking
Returns whether mouselook mode is active.
isLooking = IsMouselooking()
Returns:
isLookingTrue if mouselook mode is active; otherwise false (boolean)
IsMuted
Returns whether a character has been muted by the player.
muted = IsMuted(“unit“) or IsMuted(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query (string)
Returns:
muted1if the unit is muted; otherwise nil (1nil)
IsOutOfBounds
Returns whether the player is currently outside the bounds of the world.
outOfBounds = IsOutOfBounds()
Used in the default UI (in conjunction with IsFalling()) to allow the player
to release to a graveyard if the character has encountered a bug and fallen
underneath the world geometry.
Returns:
outOfBounds1if the player is currently outside the bounds of the world; oth-
erwise nil (1nil)
IsOutdoors
Returns whether the player is currently outdoors.
isOutdoors = IsOutdoors()
‘‘Outdoors’’ as defined by this function corresponds to the ability to use a
mount in that specific location, not necessarily whether there is a roof above
the player character’s head. For example, returns 1 in Ironforge, Undercity, and
the Caverns of Time, but nil in the nominally outdoor areas of instances such
as Stratholme, Drak’tharon Keep, and Hellfire Ramparts. (Note that even in
854 Part IV Reference
‘‘outdoor’’ areas, standing on top of certain objects may interfere with the
player’s ability to mount up.)
Returns:
isOutdoors1if the player is currently outdoors; otherwise nil (1nil)
IsPVPTimerRunning
Returns whether the player’s PvP flag will expire after a period of time.
isRunning = IsPVPTimerRunning()
If in a zone that flags the player for PvP, or if the player has manually enabled
PvP, the flag will not expire. Once not in such a zone, or once the player has
manually disabled PvP, or if the player has been flagged by attacking an
enemy unit, the timer starts running and the player’s PvP flag will expire after
some time.
Returns:
isRunning1if the player’s PvP flag will expire; otherwise nil (1nil)
IsPartyLeader
Returns whether the player is the party leader.
isLeader = IsPartyLeader()
Returns:
isLeader1if the player is the party leader; otherwise nil (1nil)
IsPassiveSpell
Returns whether a spell is passive (cannot be cast).
isPassive = IsPassiveSpell(index, “bookType“) or IsPassiveSpell(“name“)
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
Returns:
isPassive1if the spell is passive; otherwise nil (1nil)
Example:
-- prints a list of passive spells in the player’s spellbook
local numTabs = GetNumSpellTabs()
for tabID=1,numTabs do
local name,texture,offset,numSpells = GetSpellTabInfo(tabID)
for spellID = offset + 1, offset + numSpells do
if IsPassiveSpell(spellID, BOOKTYPE_SPELL) then
local spell,rank = GetSpellName(spellID, BOOKTYPE_SPELL)
Chapter 27 API Reference 855
print(“ - “ .. spell)
end
end
end
IsPetAttackActive
Returns whether the pet’s attack action is currently active.
isActive = IsPetAttackActive()
Returns:
isActive1if the pet’s attack action is currently active; otherwise nil (1nil)
IsPlayerResolutionAvailable
Returns whether the current hardware supports high resolution player
textures.
isAvailable = IsPlayerResolutionAvailable()
Returns:
isAvailable1if high-resolution player textures can be enabled; otherwise
nil (1nil)
IsPossessBarVisible
Returns whether a special action bar should be shown while the player
possesses another unit.
isVisible = IsPossessBarVisible()
Used in the default UI to switch between using the ShapeshiftBarFrame or
PossessBarFrame to show actions belonging to the possessed unit.
Returns:
isVisible1if the possessed unit’s actions should be shown on a special
action bar (1nil)
IsQuestCompletable
Returns whether the player can complete the quest presented by a questgiver.
isCompletable = IsQuestCompletable()
Returns:
isCompletable1if the player currently meets the requirements (e.g.
number of items collected) complete the quest; otherwise nil (1nil)
IsQuestLogSpecialItemInRange
Returns whether the player’s target is in range for using an item associated
with a current quest.
inRange = IsQuestLogSpecialItemInRange(questIndex)
Available for a number of quests which involve using an item (i.e. ‘‘Use the
MacGuffin to summon and defeat the boss’’, ‘‘Use this saw to fell
12 trees’’, etc.)
Arguments:
questIndexIndex of a quest log entry with an associated usable
item (between 1and GetNumQuestLogEntries())(number)
856 Part IV Reference
Returns:
inRange1if the player is close enough to the target to use the item;
0ifthetargetisoutofrange;nil if the quest item does not require a target
(number)
IsQuestWatched
Returns whether a quest from the quest log is listed in the objectives tracker.
isWatched = IsQuestWatched(questIndex)
Arguments:
questIndexIndex of a quest in the quest log (between 1and
GetNumQuestLogEntries())(number)
Returns:
isWatched1if the quest is being watched; otherwise nil (1nil)
IsRaidLeader
Returns whether the player is the raid leader.
isLeader = IsRaidLeader()
Returns:
isLeader1if the player is the raid leader; otherwise nil (1nil)
IsRaidOfficer
Returns whether the player is a raid assistant.
isRaidOfficer = IsRaidOfficer()
Returns:
isRaidOfficer1if the player is a raid assistant; otherwise nil (boolean)
IsRealPartyLeader
Returns whether the player is the leader of a non-battleground party.
isLeader = IsRealPartyLeader()
When the player is in a party/raid and joins a battleground or arena, the
normal party/raid functions refer to the battleground’s party/raid, but the
game still keeps track of the player’s place in a non-battleground party/raid.
Returns:
isLeader1if the player is the leader of a non-battleground party; otherwise
nil (1nil)
IsRealRaidLeader
Returns whether the player is the leader of a non-battleground raid.
isLeader = IsRealRaidLeader()
When the player is in a party/raid and joins a battleground or arena, the
normal party/raid functions refer to the battleground’s party/raid, but the
game still keeps track of the player’s place in a non-battleground party/raid.
Returns:
isLeader1if the player is the leader of a non-battleground raid; otherwise
nil (1nil)
Chapter 27 API Reference 857
IsReferAFriendLinked
Returns whether a unit’s account is linked to the player’s via the
Recruit-a-Friend program.
isLinked = IsReferAFriendLinked(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
isLinked1if the unit’s account is linked to the player’s (1nil)
IsResting
Returns whether the player is currently resting.
resting = IsResting()
Rest state is provided in Inns and major cities and allows the player to log out
immediately (instead of after a brief delay) and accrue bonus XP to be awarded
for kills.
Returns:
resting1if the player is resting; otherwise nil (boolean)
IsRightAltKeyDown
Returns whether the right Alt key is currently held down.
isDown = IsRightAltKeyDown()
(Note: The Mac WoW client does not distingish between left and right modifier
keys, so both Alt keys are reported as Left Alt.)
Returns:
isDown1if the right Alt key on the keyboard is currently held down; other-
wise nil (1nil)
IsRightControlKeyDown
Returns whether the right Control key on the keyboard is held down.
isDown = IsRightControlKeyDown()
(Note: The Mac WoW client does not distingish between left and right modifier
keys, so both Control keys are reported as Left Control.)
Returns:
isDown1if the right Control key on the keyboard is held down; otherwise nil
(1nil)
IsRightShiftKeyDown
Returns whether the right shift key on the keyboard is held down.
isDown = IsRightShiftKeyDown()
(Note: The Mac WoW client does not distingish between left and right modifier
keys, so both Shift keys are reported as Left Shift.)
Returns:
isDown1if the right shift key on the keyboard is currently held down; other-
wise nil (1nil)
858 Part IV Reference
IsSelectedSpell
Returns whether a spell is currently selected in the spellbook.
isSelected = IsSelectedSpell(index, “bookType“) or i
IsSelectedSpell(“name“)
Applies when ‘‘casting’’ a spell that opens a trade skill.
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
Returns:
isSelected1if the spell is currently selected; otherwise nil (1nil)
IsShiftKeyDown
Returns whether a Shift key on the keyboard is held down.
isDown = IsShiftKeyDown()
Returns:
isDown1if a Shift key on the keyboard is currently held down; otherwise nil
(1nil)
IsSilenced
Returns whether a character is silenced on a chat channel.
isSilenced = IsSilenced(“name“, “channel“)
Arguments:
nameName of a character (string)
channelName of a chat channel (string)
Returns:
isSilenced1if the character is silenced on the given channel; otherwise nil
(1nil)
IsSpellInRange
Returns whether the player is in range to cast a spell on a unit.
inRange = IsSpellInRange(index, “bookType“, “unit“) or i
IsSpellInRange(“name“, “unit“)
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
unitA unit to target with the spell (string,unitID)
Chapter 27 API Reference 859
Returns:
inRange1if the player is near enough to cast the spell on the unit; 0
if not in range; nil if the unit is not a valid target for the spell (1nil)
IsSpellKnown
Returns whether the player (or pet) knows a spell.
isKnown = IsSpellKnown(spellID [, isPet])
Arguments:
spellIDNumeric ID of a spell (number, spellID)
isPet (optional)True to check only spells known to the player’s pet;
false or omitted to check only spells known to the player (boolean)
Returns:
isKnownTrue if the player (or pet) knows the given spell; false otherwise
(boolean)
IsStackableAction
Returns whether an action uses stackable items.
isStackable = IsStackableAction(slot)
Applies to consumable items such as potions, wizard oils, food and drink; not
used for spells which consume reagents (for those, see IsConsumableAction).
Arguments:
slotAn action bar slot (number,actionID)
Returns:
isStackable1if the action uses stackable items; otherwise nil (1nil)
Example:
-- Print all “stackable actions“ to your chat window
for i=1,120 do
if IsStackableAction(i) then
local count = GetActionCount(i)
local t,id = GetActionInfo(i)
local name = GetItemInfo(id)
print(“Action:“, i, “Item:“, name, “Count:“, count)
end
end
IsStealthed
Returns whether the player is currently stealthed.
stealthed = IsStealthed()
Returns:
stealthed1if rogue Stealth, druid cat form Prowl, or a similar ability is
active on the player; otherwise nil (1nil)
IsStereoVideoAvailable
Returns whether the current system supports stereoscopic 3D display.
isAvailable = IsStereoVideoAvailable()
860 Part IV Reference
Returns:
isAvailable1if video options for stereoscopic 3D display should be shown;
otherwise nil (1nil)
IsSubZonePVPPOI
Returns whether the current area has PvP (or other) objectives to be displayed.
isPVPPOI = IsSubZonePVPPOI()
Used in the default UI when the ‘‘Display World PVP Objectives’’ setting is set
to \Dynamic\, in which case objective information is only shown when the
player is near an objective. Examples include the towers in Eastern
Plaguelands and Hellfire Peninsula as well as non-PvP objectives such as in the
Old Hillsbrad instance, the Death Knight starter quests, and the Battle for
Undercity quest event.
Returns:
isPVPPOI1if the current subzone has objectives to display (1nil)
IsSwimming
Returns whether the player is currently swimming.
isSwimming = IsSwimming()
‘‘Swimming’’ as defined by this function corresponds to the ability to use
swimming abilities (such as druid Aquatic Form) or inability to use land-
restricted abilities (such as eating or summoning a flying mount), not
necessarily to whether the player is in water.
Returns:
isSwimming1if the player is currently swimming; otherwise nil (1nil)
IsThreatWarningEnabled
Returns whether the default Aggro Warning UI should currently be shown.
enabled = IsThreatWarningEnabled()
This function (and the threatWarning CVar that affects its behavior) has no
effect on other threat APIs; it merely indicates whether Blizzard’s threat
warning UI should be displayed.
Returns:
enabled1if the Aggro Warning UI should be displayed; nil otherwise
(1nil)
IsTitleKnown
Returns whether the player has earned the ability to display a title.
isKnown = IsTitleKnown(titleIndex)
Arguments:
titleIndexIndex of a title available to the player (between 1and
GetNumTitles())(integer)
Chapter 27 API Reference 861
Returns:
isKnown1if the player has earned the ability to display the title; otherwise
nil (1nil)
IsTrackedAchievement
Returns whether an achievement is flagged for display in the objectives
tracker UI.
isTracked = IsTrackedAchievement(id)
Arguments:
idThe numeric ID of an achievement (number)
Returns:
isTrackedTrue if the achievement is flagged for tracking; otherwise false
(boolean)
IsTradeSkillLinked
Returns whether the TradeSkill UI is showing another player’s skill.
isLinked, name = IsTradeSkillLinked()
Returns:
isLinked1if the TradeSkill APIs currently reflect another character’s
tradeskill; nil if showing the player’s tradeskill or if no skill is shown (1nil)
nameIf showing another character’s skill, the name of that character (string)
IsTradeskillTrainer
Returns whether the player is interacting with a trade skill trainer (as opposed
to a class trainer).
isTradeskill = IsTradeskillTrainer()
Returns:
isTradeskill1if interacting with a trade skill trainer; otherwise nil (1nil)
IsTrainerServiceSkillStep
Returns whether a trainer service is a trade skill level.
isSkillStep = IsTrainerServiceSkillStep(index)
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
Returns:
isSkillStep1if the service is a trade skill level (e.g. Apprentice vs
Journeyman First Aid); nil if the service is a spell or recipe (1nil)
IsUnitOnQuest
Returns whether a unit is on one of the quests in the player’s quest log.
state = IsUnitOnQuest(index, “unit“) or IsUnitOnQuest(index, “name“)
Arguments:
indexIndex of a quest in the player’s quest log (between 1and GetNumQuest
LogEntries())(number)
862 Part IV Reference
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
state1if the unit is on the quest; otherwise nil (1nil)
IsUsableAction
Returns whether an action is usable.
isUsable, notEnoughMana = IsUsableAction(slot)
Arguments:
slotAn action bar slot (number,actionID)
Returns:
isUsable1if the action is usable; otherwise nil (1nil)
notEnoughMana1if the player lacks the resources (e.g. mana, energy, runes)
to use the action; otherwise nil (1nil)
IsUsableItem
Returns whether an item can currently be used.
isUsable, notEnoughMana = IsUsableItem(itemID) or i
IsUsableItem(“itemName“) or IsUsableItem(“itemLink“)
Does not account for item cooldowns (see GetItemCooldown();returns1if
other conditions allow for using the item (e.g. if the item can only be used
while outdoors).
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s link (string)
Returns:
isUsable1if the item is usable; otherwise nil (1nil)
notEnoughMana1if the player lacks the resources (e.g. mana, energy, runes)
to use the item; otherwise nil (1nil)
IsUsableSpell
Returns whether or not a given spell is usable or cannot be used due to lack
of mana.
isUsable, notEnoughMana = IsUsableSpell(index, “bookType“) or i
IsUsableSpell(“name“)
Does not account for spell cooldowns (see GetSpellCooldown();returns1if
other conditions allow for casting the spell (e.g. if the spell can only be cast
while outdoors).
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
Chapter 27 API Reference 863
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
Returns:
isUsable1if the spell is castable; otherwise nil (1nil)
notEnoughMana1if the player lacks the resources (e.g. mana, energy, runes)
to cast the spell; otherwise nil (1nil)
IsVehicleAimAngleAdjustable
Returns whether the player is controlling a vehicle weapon with adjustable aim
angle.
hasAngleControl = IsVehicleAimAngleAdjustable()
Returns:
hasAngleControl1if the player is controlling a vehicle weapon with
adjustable aim angle; otherwise nil (1nil)
IsVoiceChatAllowed
Returns whether the player is allowed to enable the voice chat feature.
isAllowed = IsVoiceChatAllowed()
Returns:
isAllowed1if voice chat is allowed; otherwise nil (1nil)
IsVoiceChatAllowedByServer
Returns whether voice chat is supported by the realm server.
IsVoiceChatEnabled
Returns whether the voice chat system is enabled.
isEnabled = IsVoiceChatEnabled()
Returns:
isEnabled1if the voice chat system is enabled; otherwise nil (1nil)
IsWindowsClient
Returns whether the player is using the Windows game client.
isWindows = IsWindowsClient()
Returns:
isWindows1if running the Windows client; otherwise nil (1nil)
IsXPUserDisabled
Returns whether experience gain has been disabled for the player.
isDisabled = IsXPUserDisabled()
Returns:
isDisabledTrue if experience gain has been disabled for the player; false
otherwise (boolean)
864 Part IV Reference
ItemHasRange
Returns whether an item has a range limitation for its use.
hasRange = ItemHasRange(itemID) or ItemHasRange(“itemName“) or i
ItemHasRange(“itemLink“)
For example, Mistletoe can only be used on another character within a given
range of the player, but a Hearthstone has no target and thus no range
restriction. Returns nil for items which have a range restriction but are
area-targeted and not unit-targeted (e.g. grenades).
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Returns:
hasRange1if the item has an effective range; otherwise nil.(1nil)
ItemTextGetCreator
Returns the original author of the currently viewed text item.
creator = ItemTextGetCreator()
Used for mail messages sent by other players; when the player makes a
permanent copy of a letter and reads it from inventory, the default UI uses this
function to display a signature (e.g. ‘‘From, Leeroy’’) at the end of the
message text.
Returns:
creatorCreator of the text item, or nil if not available (string)
ItemTextGetItem
Returns the name of the currently viewed text item.
text = ItemTextGetItem()
Used for readable world objects (plaques, books on tables, etc) and readable
inventory items (looted books/parchments/scrolls/etc, or saved copies of mail
messages). For saved mail messages the name returned is always ‘‘Plain
Letter’’ (or localized equivalent); the message subject is lost when saving
acopy.
Returns:
text—Name of the text item (string)
ItemTextGetMaterial
Returns display style information for the currently viewed text item.
material = ItemTextGetMaterial()
Chapter 27 API Reference 865
The value returned can be used to look up background textures and text colors
for display:
Background textures displayed in the default UI can be found by
prepending “Interface\\ItemTextFrame\\ItemText-“ and appending
“-TopLeft“,“-TopRight“,“-BotLeft“,“-BotRight“ to the material
string (e.g. “Interface\\ItemTextFrame\\ItemText-Stone-TopLeft“).
Colors for body and title text can be found by calling GetMaterialText
Colors(material) (a Lua function implemented in the Blizzard UI).
In cases where this function returns nil, the default UI uses the colors and
textures for ‘‘Parchment’’.
Returns:
materialString identifying a display style for the current text item, or nil for
the default style (string)
BronzeColored metallic background
MarbleLight stone background
ParchmentYellowed parchment background (default)
SilverGray metallic background
StoneDark stone background
ItemTextGetPage
Returns the current page number in the currently viewed text item.
page = ItemTextGetPage()
Returns:
pageNumber of the currently displayed page (number)
ItemTextGetText
Returns the text of the currently viewed text item.
text = ItemTextGetText()
Used for readable world objects (plaques, books on tables, etc) and readable
inventory items (looted books/parchments/scrolls/etc, or saved copies of mail
messages). Returns valid data only between the ITEM_TEXT_BEGIN and
ITEM_TEXT_CLOSED events, with the ITEM_TEXT_READY event indicating
when new text is available (as when changing pages).
Returns:
textText to be displayed for the current page of the currently viewed text
item (string)
ItemTextHasNextPage
Returns whether the currently viewed text item has additional pages.
next = ItemTextHasNextPage()
Returns:
next1if the currently viewed text item has one or more pages beyond the cur-
rent page; otherwise nil (1nil)
866 Part IV Reference
ItemTextNextPage
Moves to the next page in the currently viewed text item.
The ITEM_TEXT_READY event fires when text for the next page becomes
available. Does nothing if already viewing the last page of text.
ItemTextPrevPage
Moves to the previous page in the currently viewed text item.
The ITEM_TEXT_READY event fires when text for the previous page becomes
available. Does nothing if already viewing the first page of text.
JoinBattlefield
Joins the queue for a battleground instance.
JoinBattlefield(index, asGroup)
Arguments:
indexIndex in the battleground queue listing (1for the first avail-
able instance, or between 2 and GetNumBattlefields() for other instances)
(number)
asGroupTrue to enter the player’s entire party/raid in the queue; false to
enter the player only (boolean)
JoinPermanentChannel
Joins a channel, saving associated chat window settings.
zoneChannel, channelName = JoinPermanentChannel(“name“ i
[, “password“ [, chatFrameIndex [, enableVoice]]])
Arguments:
nameName of the channel to join (string)
password (optional)Password to use when joining (string)
chatFrameIndex (optional)Index of a chat frame (between 1and
NUM_CHAT_WINDOWS) in which to subscribe to the channel (number)
enableVoice (optional)True to enable voice in the channel; otherwise false
(boolean)
Returns:
zoneChannel0 for non-zone channels, otherwise a numeric index specific to
that channel (number)
channelNameDisplay name of the channel, if the channel was a zone channel
(string)
Example:
-- Join a custom channel “Monkeys“ with voice enabled
JoinPermanentChannel(“Monkeys“, nil, 1, 1)
JoinTemporaryChannel
Joins a channel, but does not save associated chat window settings.
JoinTemporaryChannel(“channel“)
Chapter 27 API Reference 867
Arguments:
channelName of a channel to join (string)
Protected JumpOrAscendStart
Causes the player character to jump (or begins ascent if swimming or flying).
Used by the JUMP binding, which also controls ascent when swimming or
flying.
KBArticle_BeginLoading
Requests a specific knowledge base article from the server.
KBArticle_BeginLoading(articleId, searchType)
Arguments:
articleIdThe unique articleId to request (number)
searchTypeThe search type of the request (number)
1Default ‘‘top issues’’ search
2Search for specific text
KBArticle_GetData
Returns information about the last requested knowledge base article.
id, subject, subjectAlt, text, keywords, languageId, isHot = i
KBArticle_GetData()
Only available once the KNOWLEDGE_BASE_ARTICLE_LOAD_SUCCESS event has
fired following an article request.
Returns:
idA unique identifier for the article (number)
subjectThe subject of the article (string)
subjectAltAlternate text for the article subject (string)
textThe body of the article (string)
keywordsA comma separated list of keywords for the article (string)
languageIdIdentifier for the article’s language (ee KBSetup_Get
LanguageData)(number)
isHottrue if the article is a ‘‘Hot Item’’, otherwise false (boolean)
KBArticle_IsLoaded
Returns whether the requested knowledge base article has been loaded.
isLoaded = KBArticle_IsLoaded()
The KNOWLEDGE_BASE_ARTICLE_LOAD_SUCCESS also indicates that the
requested article is available; this function presents an alternative that can be
used across UI reloads or login/logout.
Returns:
isLoadedTrue if data for the last requested article is available; otherwise
false (boolean)
868 Part IV Reference
KBQuery_BeginLoading
Queries the knowledge base server for articles.
KBQuery_BeginLoading(“searchText“, categoryIndex, subcategoryIndex, i
numArticles, page)
Arguments:
searchTextThe search string to use. The empty string will search for all arti-
cles in the given category (string)
categoryIndex—The category index (number)
subcategoryIndexThe subcategory index (number)
numArticlesThe number of articles to be returned for each page (number)
pageThe page of the total results that should be displayed. (number)
KBQuery_GetArticleHeaderCount
Returns the number of articles on the current knowledge base search
result page.
articleHeaderCount = KBQuery_GetArticleHeaderCount()
Returns:
articleHeaderCountThe number of articles on the current knowledge base
search result base page (number)
KBQuery_GetArticleHeaderData
Returns information about an article returned in a knowledge base query.
articleId, title, isHotIssue, isRecentlyUpdated = i
KBQuery_GetArticleHeaderData(index)
Arguments:
indexThe index of the article to query (number)
Returns:
articleIdA unique articleId for the article (number)
titleThe title of the article (string)
isHotIssuetrue if the article is a ‘‘Hot Issue’’, otherwise false (boolean)
isRecentlyUpdatedtrue if the article has been recently updated, otherwise
false (boolean)
KBQuery_GetTotalArticleCount
Returns the total number of articles returned for the given query.
totalArticleHeaderCount = KBQuery_GetTotalArticleCount()
Returns:
totalArticleHeaderCountThe total number of articles returned for the
given query (number)
KBQuery_IsLoaded
Returns whether results of a knowledge base query have been loaded.
isLoaded = KBQuery_IsLoaded()
Chapter 27 API Reference 869
The KNOWLEDGE_BASE_QUERY_LOAD_SUCCESS also indicates that the
requested results are available; this function presents an alternative that can be
used across UI reloads or login/logout.
Returns:
isLoadedTrue if query results are available; otherwise false (boolean)
KBSetup_BeginLoading
Loads a maximum number of ‘‘Top Issues’’ from a given page.
KBSetup_BeginLoading(numArticles, currentPage)
Arguments:
numArticlesThe number of articles displayed per page. This is
typically the constant KBASE_NUM_ARTICLES_PER_PAGE (number)
currentPage—The page to display (number)
KBSetup_GetArticleHeaderCount
Returns the number of ‘‘Top Issues’’ articles on the current page.
articleHeaderCount = KBSetup_GetArticleHeaderCount()
Returns:
articleHeaderCountThe number of ‘‘Top Issues’’ articles on the current
page (number)
KBSetup_GetArticleHeaderData
Returns header information about a ‘‘Top Issue’’ article.
articleId, title, isHotIssue, isRecentlyUpdated = i
KBSetup_GetArticleHeaderData(index)
Arguments:
indexThe index of the article to query (number)
Returns:
articleIdA unique articleId for the article (number)
titleThe title of the article (string)
isHotIssuetrue if the article is a ‘‘Hot Issue’’, otherwise false (boolean)
isRecentlyUpdatedtrue if the article has been recently updated, otherwise
false (boolean)
KBSetup_GetCategoryCount
Returns the number of available knowledge base categories.
numCategories = KBSetup_GetCategoryCount()
Returns:
numCategoriesThe number of available knowledge base categories (number)
KBSetup_GetCategoryData
Returns information about a knowledge base category.
categoryId, name = KBSetup_GetCategoryData(index)
Arguments:
indexThe index of the category (number)
870 Part IV Reference
Returns:
categoryIdThe unique identifier for the given category (number)
nameThe name of the category (string)
KBSetup_GetLanguageCount
Returns the number of available knowledge base languages.
numLanguages = KBSetup_GetLanguageCount()
Returns:
numLanguagesThe number of available knowledge base languages (number)
KBSetup_GetLanguageData
Returns information about a given knowledge base language.
languageId, name = KBSetup_GetLanguageData(index)
Arguments:
indexIndex of a language to query (between 1and KBSetup_Get
LanguageCount() (number)
Returns:
languageIdA number identifying the language in article headers (number)
nameThe name of the language (string)
KBSetup_GetSubCategoryCount
Returns the number of available subcategories for a given category.
numSubCategories = KBSetup_GetSubCategoryCount(index)
Arguments:
indexThe index of the category (number)
Returns:
numSubCategoriesThe number of available subcategories (number)
KBSetup_GetSubCategoryData
Returns information a knowledge base subcategory.
categoryId, name = KBSetup_GetSubCategoryData(index, subindex)
Arguments:
indexThe index of the category (number)
subindexThe index of the subcategory (number)
Returns:
categoryIdThe unique categoryId for the given subcategory (number)
nameThe name of the subcategory (string)
KBSetup_GetTotalArticleCount
Returns the number of ‘‘Top Issues’’ articles.
numArticles = KBSetup_GetTotalArticleCount()
Returns:
numArticlesThe total number of ‘‘Top Issues’’ articles (number)
Chapter 27 API Reference 871
KBSetup_IsLoaded
Returns whether the knowledge base default query has completed
successfully.
isLoaded = KBSetup_IsLoaded()
The KNOWLEDGE_BASE_SETUP_LOAD_SUCCESS also indicates that the
knowledge base setup is complete; this function presents an alternative that
can be used across UI reloads or login/logout.
Returns:
isLoadedTrue if results for the knowledge base’s default ‘‘Top Issues’’
query are available; false if a query is in progress or has failed (boolean)
KBSystem_GetMOTD
Returns the currently knowledge base MOTD.
text = KBSystem_GetMOTD()
Returns:
textThe message of the day for the knowledge base system (string)
KBSystem_GetServerNotice
Returns the text of the knowledge base server system notice.
text = KBSystem_GetServerNotice()
Returns:
textThe text of the knowledgebase system server notice (string)
KBSystem_GetServerStatus
Returns the knowledge base server system status message.
statusMessage = KBSystem_GetServerStatus()
Returns:
statusMessageThe knowledge base server status message, or nil (string)
KeyRingButtonIDToInvSlotID
Returns the inventoryID corresponding to a slot in the keyring.
slot = KeyRingButtonIDToInvSlotID(slot)
Arguments:
slotIndex of a key slot within the keyring (number, containerSlotID)
Returns:
slotIdentifier for the key slot usable with Inventory APIs (number,invento-
ryID)
LFGQuery
Requests Looking for More information from the server.
LFGQuery(type, index)
Query results are not available immediately; the UPDATE_LFG_LIST event fires
when data becomes available; listing information can then be retrieved using
GetLFGResults() or related APIs.
872 Part IV Reference
Arguments:
typeIndex of an LFG query type (in the list returned by GetLFGTypes())
(number)
indexIndex of an LFG entry (in the list returned by GetLFGTypeEntries
(type))(number)
Confirmation LearnPreviewTalents
Commits changes made in the Talent UI’s preview mode.
LearnPreviewTalents(isPet)
Arguments:
isPettrue to edit talents for the player’s pet, false to edit talents for the
player (boolean)
LearnTalent
Learns a talent, spending one talent point.
LearnTalent(tabIndex, talentIndex, isPet, talentGroup)
Arguments:
tabIndexIndex of a talent tab (between 1and GetNumTalentTabs())
(number)
talentIndexIndex of a talent option (between 1and GetNumTalents())
(number)
isPetTrue to edit talents for the player’s pet, false to edit talents for the
player (boolean)
talentGroupWhich set of talents to edit, if the player has Dual Talent Special-
ization enabled (number)
1Primary Talents
2—Secondary Talents
nilCurrently active talents
LeaveBattlefield
Immediately exits the current battleground instance.
Returns the player to the location from which he or she joined the battleground
and applies the Deserter debuff.
LeaveChannelByName
Leaves a chat channel.
LeaveChannelByName(“name“)
Arguments:
nameName of a chat channel to leave (string)
LeaveParty
Exits the current party or raid.
If there are only two characters in the party or raid, causes the party or raid to
be disbanded.
Chapter 27 API Reference 873
ListChannelByName
Requests the list of participants in a chat channel.
ListChannelByName(“channel“) or ListChannelByName(channelIndex)
Fires the CHAT_MSG_CHANNEL_LIST event listing the names of all characters in
the channel.
Arguments:
channelName of a channel (string)
channelIndexIndex of a channel (number)
ListChannels
Requests a list of channels joined by the player.
Fires the CHAT_MSG_CHANNEL_LIST event listing the names and indices of all
channels joined by the player.
LoadAddOn
Loads a LoadOnDemand-capable addon.
loaded, reason = LoadAddOn(“name“) or LoadAddOn(index)
If the given addon has dependencies which are also LoadOnDemand-capable,
those addons will be loaded as well. This function will not load disabled
addons.
Arguments:
nameName of an addon (name of the addon’s folder and TOC file, not the Title
found in the TOC) (string)
indexIndex of an addon in the addon list (between 1and GetNumAddOns())
(number)
Returns:
loaded1if loading the addon was successful; otherwise nil (number)
reasonIf the addon could not be loaded, an unlocalized string token
indicating the reason for failure. Localized strings for display can be found by
prepending “ADDON_“;e.g.ADDON_DEP_MISSING == “Dependency missing“.
(string)
BANNEDBanned
CORRUPTCorrupt
DEP_BANNEDDependency banned
DEP_CORRUPTDependency corrupt
DEP_DISABLEDDependency disabled
DEP_INCOMPATIBLEDependency incompatible
DEP_INSECUREDependency insecure
DEP_INTERFACE_VERSIONDependency out of date
DEP_MISSINGDependency missing
DEP_NOT_DEMAND_LOADEDDependency not loadable on demand
DISABLEDDisabled
INCOMPATIBLE—Incompatible
874 Part IV Reference
INSECURE—Insecure
INTERFACE_VERSION—Out of Date
MISSINGMissing
NOT_DEMAND_LOADEDNot loadable on demand
LoadBindings
Loads a set of key bindings.
LoadBindings(set)
The UPDATE_BINDINGS event fires when the new bindings have taken effect.
Arguments:
setA set of key bindings to load (number)
0Default key bindings
1Account-wide key bindings
2Character-specific key bindings
LoggingChat
Enables or disables saving chat text to a file.
isLogging = LoggingChat(toggle)
Text received via the chat system (but not necessarily all text displayed in chat
windows) will be saved to the file Logs/WoWChatLog.txt (path is relative to
the folder containing the World of Warcraft client); the file is not actually
updated until the player logs out.
Chat text in the log file follows a similar format to its display in-game, but with
added timestamps.
Arguments:
toggleTrue to enable chat logging; false or omitted to disable (boolean)
Returns:
isLogging1if chat logging is enabled; otherwise nil (1nil)
Example:
-- example log
6/7 16:51:26.790 Gorrok has come online.
6/7 16:51:30.054 [3. tehgladiators] Gorrok joined channel.
6/7 16:52:18.553 |Hchannel:Guild|h[Guild]|h Spin: Bah!
6/7 16:52:27.803 |Hchannel:Guild|h[Guild]|h Spin: Got Mr. Pinchy, but
first one was just a buff
6/7 16:52:41.752 |Hchannel:Guild|h[Guild]|h Valiant: ah well, maybe
the next time
6/7 16:52:57.504 [1. Trade] Yolanda: need healer premade EOTS
LoggingCombat
Enables or disables saving combat log data to a file.
isLogging = LoggingCombat(toggle)
Chapter 27 API Reference 875
Combat log data will be saved to the file Logs/WoWCombatLog.txt (path is
relative to the folder containing the World of Warcraft client); the file is not
actually updated until the player logs out.
Arguments:
toggleTrue to enable combat logging; false or omitted to disable (boolean)
Returns:
isLogging1if combat logging is enabled; otherwise nil (1nil)
Example:
-- example log file contents
6/7 17:08:46.784 SPELL_CAST_SUCCESS,0x060000000279E425,“Gundark“,0x511,
0xF13000482C5462D1,“Timber Worg“,0x10a48,49576,“Death Grip“,0x1
6/7 17:08:47.089 SPELL_AURA_APPLIED,0x060000000279E425,“Gundark“,0x511,
0xF13000482C5462D1,“Timber Worg“,0x10a48,49560,“Death Grip“,0x1,DEBUFF
6/7 17:08:47.886 SWING_DAMAGE,0x060000000279E425,“Gundark“,0x511,0xF130
00482C5462D1,“Timber Worg“,0x10a48,374,0,1,0,0,0,nil,nil,nil
6/7 17:08:47.887 SPELL_DAMAGE,0x060000000279E425,“Gundark“,0x511,0xF130
00482C5462D1,“Timber Worg“,0x10a48,50401,“Razor Frost“,0x10,5,0,16,0,0,0
,nil,nil,nil
6/7 17:08:47.887 SPELL_AURA_APPLIED,0x060000000279E425,“Gundark“,0x511,
0xF13000482C5462D1,“Timber Worg“,0x10a48,51714,“Frost Vulnerability“,0x1
0,DEBUFF
6/7 17:08:48.207 SPELL_CAST_SUCCESS,0x060000000279E425,“Gundark“,0x511,
0xF13000482C5462D1,“Timber Worg“,0x10a48,49896,“Icy Touch“,0x10
6/7 17:08:48.327 SWING_MISSED,0xF13000482C5462D1,“Timber Worg“,0x10a48,
0x060000000279E425,“Gundark“,0x511,DODGE
6/7 17:08:48.328 SPELL_PERIODIC_HEAL,0x060000000279E425,“Gundark“,0x511
,0x060000000279E425,“Gundark“,0x511,50475,“Blood Presence“,0x1,15,15,nil
Logout
Attempts to log out and return to the character selection screen.
Results vary based on current conditions:
If the player is in combat or under other temporary restrictions
(e.g. falling), fires the UI_ERROR_MESSAGE event with a mes-
sage indicating the player cannot log out at the moment.
If the player is not in an inn, major city, or other ‘‘rest’’ area (i.e.
IsResting() returns nil), fires the PLAYER_CAMPING event, causing the
default UI to show a countdown, logging the player out after a period of
time if not canceled.
If the player is in a ‘‘rest’’ area, logs out immediately.
LootSlot
Attempts to pick up an item available as loot.
LootSlot(slot)
If the item in the loot slot binds on pickup, the LOOT_BIND_CONFIRM event
fires, indicating that ConfirmLootSlot(slot) must be called in order to
actually loot the item. Please note: if you call this while processing a
876 Part IV Reference
LOOT_OPENED event and it is the last item to be looted from the corpse, can
cause LOOT_CLOSED to fire and be processed before your LOOT_OPENED event
handler completes.
Arguments:
slotIndex of a loot slot (between 1and GetNumLootItems())(number)
LootSlotIsCoin
Returns whether a loot slot contains money.
isCoin = LootSlotIsCoin(slot)
Arguments:
slotIndex of a loot slot (between 1and GetNumLootItems())(number)
Returns:
isCoin1if the loot slot contains money; otherwise nil (1nil)
LootSlotIsItem
Returns whether a loot slot contains an item.
isItem = LootSlotIsItem(slot)
Arguments:
slotIndex of a loot slot (between 1and GetNumLootItems())(number)
Returns:
isItem1if the loot slot contains an item; otherwise nil (1nil)
MouselookStart
Enables mouselook mode, in which cursor movement rotates the camera.
MouselookStop
Disables mouselook mode.
Protected MoveAndSteerStart
Begins moving the player character forward while steering via mouse
movement.
After calling this function, the player character begins moving forward while
cursor movement rotates (or steers) the character, altering yaw (facing) and/or
pitch (vertical movement angle) as well as camera position.
Equivalent to calling both CameraOrSelectOrMoveStart and
TurnOrActionStart without calling the respective Stop functions; i.e.
holding both left and right mouse buttons down. Used by the MOVEANDSTEER
binding, which can be customized to allow alternate access to this action if the
player’s system does not allow pressing multiple mouse buttons at once.
Protected MoveAndSteerStop
Ends movement initiated by MoveAndSteerStart.
After calling this function, forward movement and character steering stops and
normal cursor movement resumes.
Used by the MOVEANDSTEER binding.
Chapter 27 API Reference 877
Protected MoveBackwardStart
Begins moving the player character backward.
Used by the MOVEBACKWARD binding.
Protected MoveBackwardStop
Ends movement initiated by MoveBackwardStart.
Protected MoveForwardStart
Begins moving the player character forward.
Used by the MOVEFORWARD binding.
Protected MoveForwardStop
Ends movement initiated by MoveForwardStart.
MoveViewDownStart
Begins orbiting the camera downward (to look upward).
MoveViewDownStop
Ends camera movement initiated by MoveViewDownStart.
MoveViewInStart
Begins zooming the camera inward (towards/through the player character).
MoveViewInStop
Ends camera movement initiated by MoveViewInStart.
MoveViewLeftStart
Begins orbiting the camera around the player character to the left.
‘‘Left’’ here is relative to the player’s facing; i.e. the camera orbits clockwise if
looking down. Moving the camera to the left causes it to look towards the
character’s right.
MoveViewLeftStop
Ends camera movement initiated by MoveViewLeftStart.
MoveViewOutStart
Begins zooming the camera outward (away from the player character).
MoveViewOutStop
Ends camera movement initiated by MoveViewOutStart.
MoveViewRightStart
Begins orbiting the camera around the player character to the right.
‘‘Right’’ here is relative to the player’s facing; i.e. the camera orbits
counter-clockwise if looking down. Moving the camera to the right causes it to
look towards the character’s left.
MoveViewRightStop
Ends camera movement initiated by MoveViewRightStart.
MoveViewUpStart
Begins orbiting the camera upward (to look down).
878 Part IV Reference
MoveViewUpStop
Ends camera movement initiated by MoveViewUpStart.
Mac OS X only MovieRecording_Cancel
Cancels video recording and compression.
If a recording is in progress, recording is stopped and the results discarded. If
compression is in progress, compression is stopped and the uncompressed
portion of the movie is deleted.
Mac OS X only MovieRecording_DataRate
Returns the data rate required for a given set of video recording parameters.
dataRate = MovieRecording_DataRate(width, framerate, sound)
The value returned is a prediction of the rate at which data will be written to
the hard drive while recording. If the hardware cannot support this data rate,
game performance may suffer and recording may stop.
Arguments:
widthWidth of the output video (in pixels) (number)
framerateNumber of video frames to be recorded per second (number)
sound1if game audio is to be captured with video; otherwise 0 (number)
Returns:
dataRateSummary of the data rate (e.g. ‘‘438.297 KB/s’’, ‘‘11.132 MB/s’’)
(string)
Example:
-- Calculate the data rate required for the following:
-- 1024x768 video at 29.97 frames per second with sound
local dataRate = MovieRecording_DataRate(1024, 29.97, 1)
print(dataRate .. “ is required for this recording.“)
Mac OS X only MovieRecording_DeleteMovie
Deletes an uncompressed movie.
MovieRecording_DeleteMovie(“filename“)
Arguments:
filenamePath to an uncompressed movie (as provided in the
MOVIE_UNCOMPRESSED_MOVIE event) (string)
Mac OS X only MovieRecording_GetAspectRatio
Returns the aspect ratio of the game display.
ratio = MovieRecording_GetAspectRatio()
Used in the default UI to calculate dimensions for scaling captured video to
predetermined widths.
For example, if the aspect ratio is 0.75 (as on a 1600x1200 screen), a movie
scaled to 640 pixels wide will be 480 pixels tall; but if the aspect ratio is 0.625
(as on a 1440x900 screen), a movie scaled to 640 pixels wide will be
400 pixels tall.
Chapter 27 API Reference 879
Returns:
ratioRatio of the game display’s width to its height (number)
Mac OS X only MovieRecording_GetMovieFullPath
Returns a path to the movie currently being recorded or compressed.
path = MovieRecording_GetMovieFullPath()
If no movie is being recorded or compressed, returns either the empty string
(““) or the path of the last movie recorded/compressed.
Returns:
pathPath to the movie currently being recorded or compressed,
relative to the folder containing the World of Warcraft app (string)
Example:
MovieRecording_GetMovieFullPath()
-- returns (e.g.) “Movies/Thunder_Bluff_060409_193403.mov“
Mac OS X only MovieRecording_GetProgress
Returns information about movie compression progress.
recovering, progress = MovieRecording_GetProgress()
Returns:
recoveringTrue if a previous compression was interrupted (e.g.
due to WoW being crashing or being forced to quit), indicating that
recovery is being attempted on the file; otherwise false (boolean)
progressProgress of the movie compression process (0 =just started, 1=fin-
ished) (number)
Mac OS X only MovieRecording_GetTime
Returns the amount of time since video recording was last started.
time = MovieRecording_GetTime()
Used in the default UI to show the length of the recording in progress when
mousing over the recording indicator on the minimap.
May return a nonsensical value if no video has been recorded since logging in.
Returns:
timeAmount of time since video recording was last started (HH:MM:SS)
(string)
Mac OS X only MovieRecording_GetViewportWidth
Returns the current width of the game display.
width = MovieRecording_GetViewportWidth()
Used in the default UI to allow the current screen resolution (or an integral
factor thereof) to be selected as the video recording resolution.
Returns:
widthWidth of the game display (number)
880 Part IV Reference
Mac OS X only MovieRecording_IsCodecSupported
Returns whether a video codec is supported on the current system.
isSupported = MovieRecording_IsCodecSupported(codecID)
Arguments:
codecIDFour-byte identifier of a QuickTime codec (number)
1635148593H.264; supported natively by Apple devices like the iPod,
iPhone and AppleTV; best ratio quality/size but slowest to compress
1768124260Apple Intermediate Codec; fastest to compress, but exclusive
to Mac OS X
1835692129Motion JPEG; faster to compress than H.264 but it will gener-
ate a bigger file
1836070006MPEG-4; supported by many digital cameras and iMovie
Returns:
isSupportedtrue if the codec is supported on the current system, otherwise
false (boolean)
Mac OS X only MovieRecording_IsCompressing
Returns whether a movie file is currently being compressed.
isCompressing = MovieRecording_IsCompressing()
Returns:
isCompressingtrue if the client is currently compressing a recording; other-
wise false (boolean)
Mac OS X only MovieRecording_IsCursorRecordingSupported
Returns whether the current system supports recording the mouse cursor in
movies.
isSupported = MovieRecording_IsCursorRecordingSupported()
Returns:
isSupportedTrue if the cursor recording option should be enabled; other-
wise false (boolean)
Mac OS X only MovieRecording_IsRecording
Returns whether movie recording is currently in progress.
isRecording = MovieRecording_IsRecording()
Returns:
isRecording1if the client is currently recording, otherwise nil (1nil)
MovieRecording_IsSupported
Returns whether movie recording is supported on the current system.
isSupported = MovieRecording_IsSupported()
Returns:
isSupportedtrue if the client supports video recording; otherwise nil
(boolean)
Chapter 27 API Reference 881
Mac OS X only MovieRecording_MaxLength
Returns the maximum length of recorded video for a given set of video
recording parameters.
time = MovieRecording_MaxLength(width, framerate, sound)
The value returned reflects both the data rate associated with the given
parameters and the amount of space remaining on the hard drive.
Arguments:
widthWidth of the output video (in pixels) (number)
framerateNumber of video frames to be recorded per second (number)
sound1if game audio is to be captured with video; otherwise 0 (number)
Returns:
timeMaximum length of recorded video (HH:MM:SS) (string)
Mac OS X only MovieRecording_QueueMovieToCompress
Queues an uncompressed movie for compression.
MovieRecording_QueueMovieToCompress(“filename“)
If there are no items currently in the queue the movie will begin compressing
immediately.
Arguments:
filenamePath to an uncompressed movie (as provided in the
MOVIE_UNCOMPRESSED_MOVIE event) (string)
Mac OS X only MovieRecording_SearchUncompressedMovie
Enables or disables a search for uncompressed movies.
MovieRecording_SearchUncompressedMovie(enable)
After calling this function with true,aMOVIE_UNCOMPRESSED_MOVIE fires for
the first uncompressed movie found (causing the default UI to prompt the user
to choose whether to compress, ignore, or delete the movie). Calling this
function with false ignores the movie, causing the search to continue (firing a
MOVIE_UNCOMPRESSED_MOVIE event for the next uncompressed movie found,
and so forth).
Arguments:
enableTrue to begin searching for uncompressed movies, false to ignore a
movie for compression (boolean)
Mac OS X only MovieRecording_Toggle
Begins or ends video recording.
Used by the MOVIE_RECORDING_STARTSTOP key binding.
Mac OS X only MovieRecording_ToggleGUI
Enables or disables inclusion of UI elements in a video recording.
Equivalent to the MovieRecordingGUI CVar, but provided as a convenience
for the MOVIE_RECORDING_GUI so UI recording can be turned on or off while a
movie is recording.
882 Part IV Reference
Protected
Mac OS X only
MusicPlayer_BackTrack
Causes iTunes to return to the previous track played.
Used by the iTunes Remote key bindings only available on the Mac OS X WoW
client. Only has effect while the iTunes application is open.
Protected
Mac OS X only
MusicPlayer_NextTrack
Causes iTunes to play the next track in sequence.
Used by the iTunes Remote key bindings only available on the Mac OS X WoW
client. Only has effect while the iTunes application is open.
Protected
Mac OS X only
MusicPlayer_PlayPause
Causes iTunes to start or pause playback.
Used by the iTunes Remote key bindings only available on the Mac OS X WoW
client. Only has effect while the iTunes application is open.
Protected
Mac OS X only
MusicPlayer_VolumeDown
Causes iTunes to lower its playback volume.
Affects the iTunes volume setting only, not the overall system volume or any
of WoW’s volume settings.
Used by the iTunes Remote key bindings only available on the Mac OS X WoW
client. Only has effect while the iTunes application is open.
Protected
Mac OS X only
MusicPlayer_VolumeUp
Causes iTunes to raise its playback volume.
Affects the iTunes volume setting only, not the overall system volume or any
of WoW’s volume settings.
Used by the iTunes Remote key bindings only available on the Mac OS X WoW
client. Only has effect while the iTunes application is open.
Protected NewGMTicket
Opens a new GM support ticket.
NewGMTicket(“text“, needResponse)
The default UI sets the needResponse flag to true for ‘‘Talk to a GM’’ and
‘‘Stuck’’ tickets, and false for ‘‘Report an issue’’ tickets.
Arguments:
textThe text to be sent in the ticket (string)
needResponsetrue if the issue requires personal response from a GM; other-
wise false (boolean)
NextView
Moves the camera to the next predefined setting.
There are five ‘‘slots’’ for saved camera settings, indexed 1-5. These views can
be set and accessed directly using SaveView() and SetView(), and cycled
through using NextView() and PrevView().
NoPlayTime
Returns whether the player has exceeded the allowed play time limit.
hasNoTime = NoPlayTime()
Chapter 27 API Reference 883
When in this state, the player is unable to gain loot or XP or complete quests
and cannot use trade skills; returning to normal requires logging out of the
game for a period of time (see GetBillingTimeRested).
Only used in locales where the length of play sessions is restricted
(e.g. mainland China).
Returns:
hasNoTime1if the player is out of play time, otherwise nil (1nil)
NotWhileDeadError
Causes the default UI to display an error message indicating that actions are
disallowed while the player is dead.
Fires a UI_ERROR_MESSAGE event containing a localized message identified by
the global variable ERR_PLAYER_DEAD.
NotifyInspect
Marks a unit for inspection and requests talent data from the server.
NotifyInspect(“unit“)
Information about the inspected item’s equipment can be retrieved
immediately using Inventory APIs (e.g.
GetInventoryItemLink(“target“,1)). Talent data is not available
immediately; the INSPECT_TALENT_READY event fires once the inspected
unit’s talent information can be retrieved using Talent APIs (e.g. GetTalent
Info(1,1,true)).
Arguments:
unitA unit to inspect (string,unitID)
NumTaxiNodes
Returns the number of flight points on the taxi map.
numNodes = NumTaxiNodes()
Only returns valid data while interacting with a flight master (i.e. between the
TAXIMAP_OPENED and TAXIMAP_CLOSED events).
Returns:
numNodesNumber of flight points on the taxi map (number)
OfferPetition
Requests an arena or guild charter signature from the targeted unit.
OffhandHasWeapon
Returns whether the player has an equipped weapon in the off hand slot.
hasWeapon = OffhandHasWeapon()
Returns:
hasWeapon1if the player has a weapon equipped in the off hand slot; other-
wise nil (1nil)
OpenCalendar
Queries the server for calendar status information.
884 Part IV Reference
May cause one or more CALENDAR_UPDATE_* events to fire depending on the
contents of the player’s calendar. In the default UI, called when the calendar is
shown.
OpeningCinematic
Displays the introductory cinematic for the player’s race.
Only has effect if the player has never gained any experience.
PartialPlayTime
Returns whether the player is near the allowed play time limit.
partialPlayTime = PartialPlayTime()
When in this state, the player receives half the normal amount of money and
XP from kills and quests and cannot use trade skills; returning to normal
requires logging out of the game for a period of time (see GetBilling
TimeRested).
Only used in locales where the length of play sessions is restricted (e.g.
mainland China).
Returns:
partialPlayTime1if the character gains only partial xp, nil if not. (1nil)
Confirmation PetAbandon
Releases the player’s pet.
For Hunter pets, this function sends the pet away, never to return (in the
default UI, it’s called when accepting the ‘‘Are you sure you want to
permanently abandon your pet?’’ dialog). For other pets, this function is
equivalent to PetDismiss().
Protected PetAggressiveMode
Enables aggressive mode for the player’s pet.
In this mode, the pet automatically attacks any nearby hostile targets.
Protected PetAttack
Instructs the pet to attack.
PetAttack([“unit“]) or PetAttack([“name“])
The pet will attack the player’s current target if no unit is specified.
Arguments:
unit (optional)A unit to attack (string,unitID)
name (optional)The name of a unit to attack (string)
PetCanBeAbandoned
Returns whether the player’s pet can be abandoned.
canAbandon = PetCanBeAbandoned()
Only Hunter pets can be permanently abandoned.
Returns:
canAbandon1if the player’s pet can be abandoned, otherwise nil (1nil)
Chapter 27 API Reference 885
PetCanBeDismissed
Returns whether a Dismiss Pet command should be available for the
player’s pet.
canDismiss = PetCanBeDismissed()
Returns 1 for hunter pets even though they use the Dismiss Pet (cast) spell
instead of a Dismiss Pet (instant) command; the value of PetCanBe
Abandoned() overrides this in causing the default UI to hide the command.
Currently unused, but may be used in the future for other pets.
Returns:
canDismiss1if a Dismiss Pet command should be available for the player’s
pet; otherwise nil (1nil)
PetCanBeRenamed
Returns whether the player’s pet can be renamed.
canRename = PetCanBeRenamed()
Only hunter pets can be renamed, and only once (barring use of a Certificate of
Ownership).
Returns:
canRename1if the player can rename the currently controlled pet, otherwise
nil (1nil)
Protected PetDefensiveMode
Enables defensive mode for the player’s pet.
In this mode, the pet automatically attacks only units which attack it or the
player or units the player is attacking.
PetDismiss
Dismisses the currently controlled pet.
Used for dismissing Warlock pets, Mind Control targets, etc. Has no effect for
Hunter pets, which can only be dismissed using the Dismiss Pet spell.
Protected PetFollow
Instructs the pet to follow the player.
If the pet is currently attacking a target, the pet will stop attacking.
PetHasActionBar
Returns whether the player’s current pet has an action bar.
hasActionBar = PetHasActionBar()
Returns:
hasActionBar—Returns 1if the player’s pet has an action bar; otherwise nil
(1nil)
Protected PetPassiveMode
Enables passive mode for the player’s pet.
In this mode, the pet will not automatically attack any target.
886 Part IV Reference
PetRename
Renames the currently controlled pet.
PetRename(“name“ [, “genitive“ [, “dative“ [, “accusative“ i
[, “instrumental“ [, “prepositional“]]]]])
Only Hunter pets can be renamed, and a given pet can only be renamed once
(barring use of a Certificate of Ownership).
Arguments:
nameNew name for the pet (nominative form on Russian clients) (string)
genitive (optional)Genitive form of the pet’s new name; applies only on
Russian clients (string)
dative (optional)Dative form of the pet’s new name; applies only on Russian
clients (string)
accusative (optional)Accusative form of the pet’s new name; applies only
on Russian clients (string)
instrumental (optional)Instrumental form of the pet’s new name; applies
only on Russian clients (string)
prepositional (optional)Prepositional form of the pet’s new name; applies
only on Russian clients (string)
Protected PetStopAttack
Instructs the pet to stop attacking.
Protected PetWait
Instructs the pet to stay at its current location.
If the pet is currently attacking a target, the pet will stop attacking.
No Combat PickupAction
Puts the contents of an action bar slot onto the cursor or the cursor contents
into an action bar slot.
PickupAction(slot)
After an action is picked up via this function, it can only be placed into other
action bar slots (with PlaceAction() or by calling PickupAction() again),
even if the action is an item which could otherwise be placed elsewhere. Unlike
many other ‘‘pickup’’ cursor functions, this function removes the picked-up
action from the source slot. An action slot can be emptied by calling this
function followed by ClearCursor().
If the action slot is empty and the cursor already holds an action, a spell, a
companion (mount or non-combat pet), a macro, an equipment set, or an item
(with a ‘‘Use:’’ effect), it is put into the action slot. If both the cursor and the
slot hold an action (or any of the above data types), the contents of the cursor
and the slot are exchanged.
Arguments:
slotAn action bar slot (number,actionID)
Chapter 27 API Reference 887
PickupBagFromSlot
Puts an equipped container onto the cursor.
PickupBagFromSlot(slot)
Arguments:
slotAn inventory slot containing a bag (see GetInventorySlotInfo(),
ContainerIDToInventoryID())(number,inventoryID)
PickupCompanion
Puts a non-combat pet or mount onto the cursor.
PickupCompanion(“type“, index)
Arguments:
typeType of companion (string)
CRITTERA non-combat pet
MOUNT—A mount
indexIndex of a companion (between 1and GetNumCompanions(type))
(number)
PickupContainerItem
Picksupanitemfromorputsanitemintoaslotinoneoftheplayersbagsor
other containers.
PickupContainerItem(container, slot)
If the cursor is empty and the referenced container slot contains an item, that
item is put onto the cursor. If the cursor contains an item and the slot is empty,
the item is placed into the slot. If both the cursor and the slot contain items, the
contents of the cursor and the container slot are exchanged.
An item picked up from a container is not removed from its slot (until put
elsewhere); when an item is picked up, the slot becomes locked, preventing
other changes to its contents until the disposition (movement, trade, mailing,
auctioning, destruction, etc) of the picked-up item is resolved.
Arguments:
containerIndex of one of the player’s bags or other containers (number,
containerID)
slotIndex of an item slot within the container (number, containerSlotID)
Example:
-- Pickup the first item in your backpack
PickupContainerItem(0, 1)
PickupEquipmentSet
Puts an equipment set (specified by index) on the cursor.
PickupEquipmentSet(index)
Can be used to place an equipment set in an action bar slot.
Arguments:
indexIndex of an equipment set (between 1and GetNumEquipmentSets())
(number)
888 Part IV Reference
PickupEquipmentSetByName
Puts an equipment set on the cursor.
PickupEquipmentSetByName(“name“)
Can be used to place an equipment set in an action bar slot.
Arguments:
nameName of an equipment set (case sensitive) (string)
PickupGuildBankItem
Picksupanitemfromorputsanitemintotheguildbank.
PickupGuildBankItem(tab, slot)
If the cursor is empty and the referenced guild bank slot contains an item, that
item is put onto the cursor. If the cursor contains an item and the slot is empty,
the item is placed into the slot. If both the cursor and the slot contain items, the
contents of the cursor and the guild bank slot are exchanged.
Arguments:
tabIndex of a guild bank tab (number)
slotIndex of an item slot in the guild bank tab (number)
PickupGuildBankMoney
Puts money from the guild bank onto the cursor.
PickupGuildBankMoney(amount)
Money is not actually withdrawn from the guild bank; in the default UI, when
the cursor ‘‘puts’’ the money into one of the player’s bags, it calls Withdraw
GuildBankMoney().
Arguments:
amountAmount of money to pick up (in copper) (number)
PickupInventoryItem
Picksupanitemfromorputsanitemintoanequipmentslot.
PickupInventoryItem(slot)
If the cursor is empty and the referenced inventory slot contains an item, that
item is put onto the cursor. If the cursor contains an item (which can be
equipped in the slot) and the slot is empty, the item is placed into the slot. If
both the cursor and the slot contain items, the contents of the cursor and the
inventory slot are exchanged.
An item picked up from an inventory slot is not removed from the slot (until
put elsewhere); when an item is picked up, the slot becomes locked, preventing
other changes to its contents until the disposition (movement, trade,
destruction, etc) of the picked-up item is resolved.
Arguments:
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
Chapter 27 API Reference 889
PickupItem
Puts an arbitrary item onto the cursor.
PickupItem(itemID) or PickupItem(“itemName“) or PickupItem(“itemLink“)
Puts an item onto the cursor regardless of its location (equipped, bags, bank or
not even in the player’s possession); can be used to put an item into an action
slot (see PlaceAction()) even if the player does not currently hold the item.
Since the item is not picked up from a specific location, this function cannot be
used to move an item to another bag, trade it to another player, attach it to a
mail message, destroy it, etc.
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
PickupMacro
Puts a macro onto the cursor.
PickupMacro(index) or PickupMacro(“name“)
Arguments:
index—Index of a macro (number,macroID)
name—Name of a macro (string)
PickupMerchantItem
Puts an item available for purchase from a vendor onto the cursor.
PickupMerchantItem(index)
Arguments:
indexIndex of an item in the vendor’s listing (between 1and
GetMerchantNumItems())(number)
PickupPetAction
Puts the contents of a pet action slot onto the cursor or the cursor contents into
a pet action slot.
PickupPetAction(index)
Only pet actions and spells from the ‘‘pet’’ portion of the spellbook can be
placed into pet action slots.
If the cursor is empty and the referenced pet action slot contains an action, that
action is put onto the cursor (but remains in the slot). If the cursor contains a
pet action or pet spell and the slot is empty, the action/spell is placed into the
slot. If both the cursor and the slot contain pet actions, the contents of the
cursor and the pet action slot are exchanged.
Arguments:
indexIndex of a pet action (between 1and NUM_PET_ACTION_SLOTS)
(number)
890 Part IV Reference
PickupPlayerMoney
Puts an amount of the player’s money onto the cursor.
PickupPlayerMoney(amount)
Money is not immediately deducted from the player’s total savings (though it
looks like it on the default UI’s money displays, which generally show
GetMoney()-GetCursorMoney()).
Arguments:
amountAmount of money to put on the cursor (in copper) (number)
PickupSpell
Puts a spell from the player’s or pet’s spellbook onto the cursor.
PickupSpell(id, “bookType“)
Arguments:
idIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
PickupStablePet
Puts a pet from the stables onto the cursor.
PickupStablePet(index)
Use with ClickStablePet to move pets between stabled and active status.
Arguments:
index—Index of a stable slot (number)
0—Active pet
1 to NUM_PET_STABLE_SLOTSA stable slot
PickupTradeMoney
Puts money offered by the player for trade onto the cursor.
PickupTradeMoney(amount)
Money put onto the cursor is subtracted from the amount offered for trade (see
GetPlayerTradeMoney()).
Arguments:
amountAmount of money to take from the trade window (in copper) (number)
Protected PitchDownStart
Begins adjusting the player character’s angle of vertical movement downward.
Affects only the angle or slope of movement for swimming or flying; has no
immediately visible effect if the player is not moving, but alters the trajectory
followed as soon as the player begins moving. Continuously adjusts pitch until
the minimum angle is reached or PitchDownStop() is called.
Used by the PITCHDOWN binding.
Chapter 27 API Reference 891
Protected PitchDownStop
Ends movement initiated by PitchDownStart.
Protected PitchUpStart
Begins adjusting the player character’s angle of vertical movement upward.
Affects only the angle or slope of movement for swimming or flying; has no
immediately visible effect if the player is not moving, but alters the trajectory
followed as soon as the player begins moving. Continuously adjusts pitch until
the maximum angle is reached or PitchUpStop() is called.
Used by the PITCHUP binding.
Protected PitchUpStop
Ends movement initiated by PitchUpStart.
No Combat PlaceAction
Puts the contents of the cursor into an action bar slot.
PlaceAction(slot)
If the action slot is empty and the cursor already holds an action, a spell, a
companion (mount or non-combat pet), a macro, an equipment set, or an item
(with a ‘‘Use:’’ effect), it is put into the action slot. If both the cursor and the
slot hold an action (or any of the above data types), the contents of the cursor
and the slot are exchanged.
Does nothing if the cursor is empty.
Arguments:
slotDestination action bar slot (number,actionID)
Confirmation PlaceAuctionBid
Places a bid on (or buys out) an auction item.
PlaceAuctionBid(“list“, index, bid)
Attempting to bid an amount equal to or greater than the auction’s buyout
price will buy out the auction (spending only the exact buyout price) instead of
placing a bid.
Arguments:
listType of auction listing (string)
bidderAuctions the player has bid on
listAuctions the player can browse and bid on or buy out
ownerAuctions the player placed
indexIndex of an auction in the listing (number)
bidAmount to bid (in copper) (number)
Confirmation PlaceGlyphInSocket
Applies the glyph currently awaiting a target to a socket.
PlaceGlyphInSocket(socket)
Only valid during glyph application: when the player has activated the glyph
item but before she has chosen the glyph slot to put it in (i.e. the glowing hand
cursor is showing).
892 Part IV Reference
This function does not ask for confirmation before overwriting an existing
glyph. However, calling this function only begins the ‘‘spellcast’’ that applies
the glyph, so canceling glyph application is still possible.
Arguments:
socketWhich glyph socket to apply the glyph to (between 1and
NUM_GLYPH_SLOTS)(number,glyphIndex)
PlayMusic
Plays an audio file as background music.
PlayMusic(“musicfile“)
Any other background music that is currently playing will be faded out as the
new music begins; if the Sound_ZoneMusicNoDelay is set, music will loop
continuously until StopMusic() is called.
WoW supports WAV, MP3 and Ogg audio formats.
Arguments:
musicfilePath to a music file (string)
Example:
-- play one of WoW’s built-in music files
PlayMusic(“Sound\\Music\\GlueScreenMusic\\wow_main_theme.mp3“)
-- play a music file from an addon
PlayMusic(“Interface\\AddOns\\MyAddOn\\MyMusic.mp3“)
PlaySound
Plays one of WoW’s built-in sound effects.
PlaySound(“sound“)
OnlysupportssoundsfoundintheSound\Interface directory within
WoWsMPQles;toplayotherbuilt-insoundsorsoundsinanaddon
directory, use PlaySoundFile().
Arguments:
soundName of a built-in sound effect (string)
Example:
PlaySound(“AuctionWindowOpen“);
PlaySoundFile
Plays an audio file at a given path.
PlaySoundFile(“soundFile“)
For a shorter way to specify one of WoW’s built-in UI sound effects, see
PlaySound().
WoW supports WAV, MP3 and Ogg audio formats.
Arguments:
soundFileA path to the sound file to be played (string)
Example:
-- play one of WoW’s built-in sound files
PlayMusic(“Sound\\Spells\\AbolishMagic.wav“)
Chapter 27 API Reference 893
-- play a sound file from an addon
PlayMusic(“Interface\\AddOns\\MyAddOn\\MySound.wav“)
PlayerCanTeleport
Returns whether the player can accept a summons.
amount = PlayerCanTeleport()
Returns:
amountTrue if the player is currently allowed to accept a summons (boolean)
PlayerIsPVPInactive
Returns whether a battleground participant is inactive (and eligible for
reporting as AFK).
isInactive = PlayerIsPVPInactive(“name“) or PlayerIsPVPInactive(“unit“)
Arguments:
nameName of a friendly player unit in the current battleground (string)
unitA friendly player unit in the current battleground (string,unitID)
Returns:
isInactiveTrue if the unit can be reported as AFK; otherwise false
(boolean)
PrevView
Moves the camera to the previous predefined setting.
There are five ‘‘slots’’ for saved camera settings, indexed 1-5. These views can
be set and accessed directly using SaveView() and SetView(), and cycled
through using NextView() and PrevView().
ProcessMapClick
Possibly changes the WorldMap based on a mouse click.
ProcessMapClick(clickX, clickY)
May change the map zone or zoom based on the click location: e.g. if the world
map shows Dragonblight and one clicks in the area labeled ‘‘Wintergrasp’’ on
the map, the current map zone changes to show Wintergrasp.
Arguments:
clickXHorizontal position of the click relative to the current world map (0 =
left edge, 1=right edge) (number)
clickYVertical position of the click relative to the current world map (0 =top,
1=bottom) (number)
PromoteToAssistant
Promotes a raid member to raid assistant.
PromoteToAssistant(“unit“) or PromoteToAssistant(“name“ [, exactMatch])
Arguments:
unitA unit in the raid (string,unitID)
nameName of a unit in the raid (string)
exactMatch (optional)True to check only units whose name exactly
matches the name given; false to allow partial matches (boolean)
894 Part IV Reference
PromoteToLeader
Promotes a player to party/raid leader.
PromoteToLeader(“unit“) or PromoteToLeader(“name“ [, exactMatch])
Arguments:
unitA unit in the party or raid (string,unitID)
name—Name of a party member (string)
exactMatch (optional)True to check only units whose name exactly
matches the name given; false to allow partial matches (boolean)
Confirmation PurchaseSlot
Purchases the next available bank slot.
Only available while interacting with a banker NPC (i.e. between the
BANKFRAME_OPENED and BANKFRAME_CLOSED events).
PutItemInBackpack
Puts the item on the cursor into the player’s backpack.
hadItem = PutItemInBackpack()
The item will be placed in the lowest numbered slot (containerSlotID)inthe
player’s backpack.
Causes an error message (UI_ERROR_MESSAGE) if the backpack is full.
Returns:
hadItem1if the cursor had an item; otherwise nil (1nil)
PutItemInBag
Puts the item on the cursor into the one of the player’s bags or other containers.
hadItem = PutItemInBag(container)
The item will be placed in the lowest numbered slot (containerSlotID)inthe
container.
Causes an error message (UI_ERROR_MESSAGE) if the container is full. Cannot
be used to place an item into the player’s backpack; see
PutItemInBackpack().
Arguments:
containerIndex of one of the player’s bags or other containers (number,con-
tainerID)
Returns:
hadItem1if the cursor had a item; otherwise nil (1nil)
QueryAuctionItems
Requests data from the server for the list of auctions meeting given search
criteria.
QueryAuctionItems([“name“ [, minLevel [, maxLevel [, invTypeIndex i
[, classIndex [, subClassIndex [, page [, isUsable [, minQuality i
[, getAll]]]]]]]]]])
If any search criterion is omitted or nil, the search will include all possible
values for that criterion.
Chapter 27 API Reference 895
Search queries are throttled, preventing abuse of the server by clients sending
too many queries in short succession. Normal queries can be sent once every
few seconds; mass queries return all results in the auction house instead of one
‘‘page’’ at a time, and can only be sent once every several minutes.
Query results are not returned immediately: the AUCTION_ITEM_LIST_UPDATE
event fires once data is available; listing information can then be retrieved
using GetAuctionItemInfo() or other Auction APIs.
Arguments:
name (optional)Full or partial item name to limit search results;
will match any item whose name contains this string (string)
minLevel (optional)Maximum required character level of items to limit
search results (number)
maxLevel (optional)Maximum required character level of items to limit
search results (number)
invTypeIndex (optional)Index of an item inventory type to limit search
results (note that GetAuctionInvTypes(classIndex, subClassIndex)
returns a list of token, display pairs for each inventory type; thus, to convert
a token index from that list for use here, divide by 2 and round up) (number)
classIndex (optional)Index of an item class to limit search results
(in the list returned by GetAuctionItemClasses())(number)
subClassIndex (optional)Index of an item subclass to limit search results (in
the list returned by GetAuctionItemSubClasses(classIndex))(number)
page (optional)Which ‘‘page’’ of search results to list, if more than
NUM_AUCTION_ITEMS_PER_PAGE (50) auctions are available; nil to query the
first (or only) page (number)
isUsable (optional)True to limit search results to only items which can be
used or equipped by the player character; otherwise false (boolean)
minQuality (optional)Minimum quality (rarity) level of items to limit search
results (itemQuality)
getAll (optional)True to perform a mass query (returning all listings at
once); false to perform a normal query (returning a large number of listings
in ‘‘pages’’ of NUM_AUCTION_ITEMS_PER_PAGE [50] at a time) (boolean)
QueryGuildBankLog
Requests the item transaction log for a guild bank tab from the server.
QueryGuildBankLog(tab)
Fires the GUILDBANKLOG_UPDATE event when transaction log information
becomes available.
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
QueryGuildBankTab
Requests information about the contents of a guild bank tab from the server.
QueryGuildBankTab(tab)
896 Part IV Reference
Fires the GUILDBANKBAGSLOTS_CHANGED event when information about the
tab’s contents becomes available.
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
QueryGuildBankText
Requests guild bank tab info text from the server.
QueryGuildBankText(tab)
The text is not returned immediately; the GUILDBANK_UPDATE_TEXT event
fires when text is available for retrieval by the GetGuildBankText()
function.
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
QueryGuildEventLog
Requests guild event log information from the server.
Fires the GUILD_EVENT_LOG_UPDATE event when event log information
becomes available.
QuestChooseRewardError
Causes the default UI to display an error message indicating that the player
must choose a reward to complete the quest presented by a questgiver.
Fires a UI_ERROR_MESSAGE event containing a localized message identified by
the global variable ERR_QUEST_MUST_CHOOSE. Choose wisely.
QuestFlagsPVP
Returns whether accepting the offered quest will flag the player for PvP.
questFlag = QuestFlagsPVP()
Only valid when the questgiver UI is showing the accept/decline stage of a
quest dialog (between the QUEST_DETAIL and QUEST_FINISHED events);
otherwise may return nil or a value from the most recently displayed quest.
Returns:
questFlag1if accepting the quest will flag the player for PvP for
as long as it remains in the quest log; otherwise nil (1nil)
QuestLogPushQuest
Shares a quest with other group members.
QuestLogPushQuest([questIndex])
Arguments:
questIndex (optional)Index of a quest in the quest log (between 1and
GetNumQuestLogEntries()); if omitted, defaults to the selected quest (number)
Quit
Attempts to exit the World of Warcraft client.
Chapter 27 API Reference 897
Results vary based on current conditions:
If the player is in combat or under other temporary restrictions
(e.g. falling), fires the UI_ERROR_MESSAGE event with a mes-
sage indicating the player cannot log out at the moment.
If the player is not in an inn, major city, or other ‘‘rest’’ area
(i.e. IsResting() returns nil), fires the PLAYER_QUITING event, causing
the default UI to show a countdown, quitting WoW after a period of time if
not canceled.
If the player is in a ‘‘rest’’ area, quits the game immediately.
RandomRoll
Initiates a public, server-side ‘‘dice roll’’.
RandomRoll(min, max)
Used in the default UI to implement the /roll chat command; when called,
the server generates a random integer and sends it to the player and all others
nearby (or in the same party/raid) via a CHAT_MSG_SYSTEM event. (The server
message is formatted according to the global RANDOM_ROLL_RESULT;e.g.
‘‘Leeroy rolls 3 (1-100)’’.)
For random number generation that does not involve the server or send visible
messages to other clients, see math.random.
Arguments:
minLowest number to be randomly chosen (number,string)
maxHighest number to be randomly chosen (number,string)
RegisterCVar
Registers a configuration variable to be saved.
RegisterCVar(“cvar“, “default“)
Arguments:
cvarName of a CVar (string)
defaultDefault value of the CVar (string)
Hardware ReloadUI
Reloads the user interface.
Saved variables are written to disk, the default UI is reloaded, and all enabled
non-LoadOnDemand addons are loaded, including any addons previously
disabled which were enabled during the session (see EnableAddOn() et al).
RemoveChatWindowChannel
Removes a channel from a chat window’s list of saved channel subscriptions.
RemoveChatWindowChannel(index, “channel“)
Used by the default UI’s function ChatFrame_RemoveChannel() which
manages the set of channel messages shown in a displayed ChatFrame.
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
channelName of the channel to remove (string)
898 Part IV Reference
RemoveChatWindowMessages
Removes a message type from a chat window’s list of saved message
subscriptions.
RemoveChatWindowMessages(index, “messageGroup“)
Used by the default UI’s functions ChatFrame_RemoveMessageGroup() and
ChatFrame_RemoveAllMessageGroups() which manage the set of message
types shown in a displayed ChatFrame.
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
messageGroupToken identifying a message type (string, chatMsgType)
RemoveFriend
Removes a character from the friends list.
RemoveFriend(“name“)
Arguments:
nameName of a character to remove from the friends list (string)
Confirmation RemoveGlyphFromSocket
Removes the glyph from a socket.
RemoveGlyphFromSocket(socket)
Arguments:
socketWhich glyph socket to query (between 1and NUM_GLYPH_SLOTS)
(number,glyphIndex)
RemoveQuestWatch
Removes a quest from the objectives tracker.
RemoveQuestWatch(questIndex)
Arguments:
questIndexIndex of a quest in the quest log (between 1and
GetNumQuestLogEntries())(number)
RemoveTrackedAchievement
Removes an achievement from the objectives tracker UI.
RemoveTrackedAchievement(id)
Arguments:
idThe numeric ID of an achievement (number)
RenameEquipmentSet
Changes the name of a saved equipment set.
RenameEquipmentSet(“name“, “newName“)
Not used in the default UI; may be deprecated in future patches.
Arguments:
nameName of an equipment set (case sensitive) (string)
newNameNew name for the set (string)
Chapter 27 API Reference 899
RenamePetition
Renames the guild or arena team to be created by the open petition.
RenamePetition(“name“)
Arguments:
nameNew name for the guild or arena team (string)
RepairAllItems
Attempts to repair all of the player’s damaged items.
RepairAllItems([useGuildMoney])
Arguments:
useGuildMoney (optional)1to use guild bank money (if avail-
able); nil or omitted to use the player’s own money (1nil)
Confirmation ReplaceEnchant
Confirms replacing an existing enchantment.
Usable in response to the REPLACE_ENCHANT event which fires when the
player attempts to apply a temporary or permanent enchantment to an item
which already has one.
Confirmation ReplaceTradeEnchant
Confirms replacement of an existing enchantment when offering an
enchantment for trade.
After confirming, the enchantment is not actually performed until both parties
accept the trade.
RepopMe
Releases the player’s spirit to the nearest graveyard.
Only has effect if the player is dead.
ReportPlayerIsPVPAFK
Reports a battleground participant as AFK.
ReportPlayerIsPVPAFK(“name“) or ReportPlayerIsPVPAFK(“unit“)
Arguments:
nameName of a friendly player unit in the current battleground (string)
unitA friendly player unit in the current battleground (string,unitID)
RequestBattlefieldPositions
Requests information from the server about team member positions in the
current battleground.
Automatically called in the default UI by UIParent’s and WorldMapFrame’s
OnUpdate handlers.
RequestBattlefieldScoreData
Requests battlefield score data from the server.
Score data is not returned immediately; the UPDATE_BATTLEFIELD_SCORE
event fires once information is available and can be retrieved by calling
GetBattlefieldScore() and related functions.
900 Part IV Reference
RequestBattlegroundInstanceInfo
Requests information about available instances of a battleground from the
server.
RequestBattlegroundInstanceInfo(index)
The PVPQUEUE_ANYWHERE_SHOW event fires once information is available; data
can then be retrieved by calling GetNumBattlefields() and
GetBattlefieldInstanceInfo().
Arguments:
indexIndex of a battleground (between 1and NUM_BATTLEGROUNDS)
(number)
RequestInspectHonorData
Requests PvP honor and arena data from the server for the currently inspected
unit.
Once the INSPECT_HONOR_UPDATE event fires, PvP honor and arena
information can be retrieved using GetInspectHonorData(team) and
GetInspectArenaTeamData().
RequestRaidInfo
Requests information about saved instances from the server.
Data is not returned immediately; the UPDATE_INSTANCE_INFO event when
the raid information is available for retrieval via GetSavedInstanceInfo()
and related functions.
RequestTimePlayed
Requests information from the server about the player character’s total time
spent online.
Information is not returned immediately; the TIME_PLAYED_MSG event fires
when the requested data is available.
ResetCPUUsage
Resets CPU usage statistics.
Only has effect if the scriptProfile CVar is set to 1.
ResetChatColors
Removes all saved color settings for chat message types, resetting them to
default values.
ResetChatWindows
Removes all saved chat window settings, resetting them to default values.
Used by the default UI’s function FCF_ ResetChatWindows() which resets
the appearance and behavior of displayed FloatingChatFrames.
ResetCursor
Returns the cursor to its normal appearance (the glove pointer) and behavior.
Has effect after the cursor image/mode has been changed via SetCursor(),
ShowContainerSellCursor(), or similar. Has no immediately visible effect
if the cursor is holding an item, spell, or other data.
Chapter 27 API Reference 901
ResetDisabledAddOns
Reverts changes to the enabled/disabled state of addons.
Any addons enabled or disabled in the current session will return to their
enabled/disabled state as of the last login or UI reload.
ResetGroupPreviewTalentPoints
Reverts all changes made in the Talent UI’s preview mode.
ResetGroupPreviewTalentPoints(isPet, talentGroup)
Arguments:
isPettrue to edit talents for the player’s pet, false to edit talents for the
player (boolean)
talentGroupWhich set of talents to edit, if the player has Dual Talent Special-
ization enabled (number)
1Primary Talents
2—Secondary Talents
nilCurrently active talents
ResetInstances
Resets all non-saved instances associated with the player.
Only instances to which the player is not saved may be reset (i.e. normal 5-man
dungeons, not heroic dungeons or raids), and only by a solo player or group
leader.
ResetPreviewTalentPoints
Reverts changes made within a specific tab in the Talent UI’s preview mode.
ResetPreviewTalentPoints(tabIndex, isPet, talentGroup)
Arguments:
tabIndexIndex of a talent school/tab (between 1and GetNumTalentTabs())
(number)
isPettrue to edit talents for the player’s pet, false to edit talents for the
player (boolean)
talentGroupWhich set of talents to edit, if the player has Dual Talent Special-
ization enabled (number)
1Primary Talents
2—Secondary Talents
nilCurrently active talents
ResetTutorials
Enables contextual tutorial display and clears the list of already displayed
tutorials.
Tutorials that have already been shown to the player will appear again (via
TUTORIAL_TRIGGER events) once their conditions are met. The first tutorial
will appear again immediately.
902 Part IV Reference
ResetView
Resets a saved camera setting to default values.
ResetView(index)
There are five ‘‘slots’’ for saved camera settings, indexed 1-5. These views can
be set and accessed directly using SaveView() and SetView(), and cycled
through using NextView() and PrevView().
Arguments:
indexIndex of a saved camera setting (between 1and 5) (number)
RespondInstanceLock
Allows leaving a recently entered instance to which the player would
otherwise be saved.
RespondInstanceLock(response)
Applies when the player enters an instance to which other members of her
group are saved; if the player leaves the instance within the time limit (see
GetInstanceLockTimeRemaining()) she will not be saved to the instance.
Arguments:
responseWhether the player wishes to remain in the instance (boolean)
falseExit to the nearest graveyard
trueRemain in the zone, saving the player to this instance
RestartGx
Restart the client’s graphic subsystem.
Does not reload the UI.
RestoreVideoEffectsDefaults
Resets video effects options to default values.
These options are shown in the Video ->Effects panel in the default UI and
include settings such as for view distance, texture resolution, and full-screen
glow.
RestoreVideoResolutionDefaults
Resets video resolution options to default values.
These options are shown in the Video ->Resolution panel in the default UI
and include settings such as screen resolution, windowed mode, and gamma.
RestoreVideoStereoDefaults
Resets stereoscopic 3D video options to default values.
These options are shown in the Video ->Stereo panel in the default UI and
include settings for convergence and eye separation.
ResurrectGetOfferer
Returns the name of a unit offering to resurrect the player.
name = ResurrectGetOfferer()
Returns nil if no resurrection has been offered or if an offer has expired.
Chapter 27 API Reference 903
Returns:
nameName of the unit offering resurrection (string)
ResurrectHasSickness
Returns whether accepting an offered resurrection spell will cause the player to
suffer Resurrection Sickness.
hasSickness = ResurrectHasSickness()
Usable following the RESURRECT_REQUEST event which fires when the player
is offered resurrection by another unit.
Generally always returns nil, as resurrection by other players does not cause
sickness.
Returns:
hasSickness1if accepting resurrection will cause Resurrection Sickness; oth-
erwise nil (1nil)
ResurrectHasTimer
Returns whether the player must wait before resurrecting.
hasTimer = ResurrectHasTimer()
Applies to resurrection spells offered by other units, resurrecting by returning
to the player’s corpse as a ghost, and to resurrecting at a graveyard’s spirit
healer, if the player has recently died several times in short succession. See
GetCorpseRecoveryDelay() for the time remaining until the player can
resurrect.
Returns:
hasTimer1if the player must wait before resurrecting; otherwise nil (1nil)
RetrieveCorpse
Confirms resurrection by returning to the player’s corpse.
ReturnInboxItem
Returns a message in the player’s inbox to its sender.
ReturnInboxItem(mailID)
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
RollOnLoot
Register the player’s intent regarding an item up for loot rolling.
RollOnLoot(id, rollType)
Rolls are not actually performed until all eligible group members have
registered their intent or the time period for rolling expires.
If the item binds on pickup, the CONFIRM_LOOT_ROLL event fires, indicating
that ConfirmLootRoll(id) must be called in order to actually roll on
the item.
904 Part IV Reference
Arguments:
idIndex of an item currently up for loot rolling (as provided in the
START_LOOT_ROLL event) (number)
rollTypeType of roll action to perform (number)
0Pass (declines the loot)
1Roll ‘‘need’’ (wins if highest roll)
2Roll ‘‘greed’’ (wins if highest roll and no other member rolls ‘‘need’’)
RunBinding
Runs the script associated with a key binding action.
RunBinding(“COMMAND“)
Note: this function is not protected, but the scripts for many default key
binding actions are (and can only be called by the Blizzard UI).
Arguments:
COMMANDName of a key binding command (string)
Example:
-- Take a screenshot
RunBinding(“SCREENSHOT“)
Protected RunMacro
Runs a macro.
RunMacro(index [, ““button““]) or RunMacro(“name“ [, ““button““])
Arguments:
index—Index of a macro (number,macroID)
name—Name of a macro (string)
“button“ (optional)The mouse button used to click the macro;
may be used by [button:_x_]options in the macro (string)
Protected RunMacroText
Runs arbitrary text as a macro.
RunMacroText(““text“ [, ““button““])
Arguments:
“text“The text of the macro to run (string)
“button“ (optional)The mouse button used to click the macro;
may be used by [button:_x_]options in the macro (string)
RunScript
Runs a string as a Lua script.
RunScript(“script“)
Arguments:
script—A Lua script to be run (string)
Example:
-- Print to chat frame
local script = “print(\“Hello World\“)“
RunScript(script)
Chapter 27 API Reference 905
SaveBindings
Saves the current set of key bindings.
SaveBindings(set)
Arguments:
setA set to which to save the current bindings (number)
1Account-wide key bindings
2Character-specific key bindings
Confirmation SaveEquipmentSet
Saves or creates an equipment set with the player’s currently equipped items.
SaveEquipmentSet(“name“, icon)
If a set with the same name already exists, that set’s contents are overwritten.
Set names are case sensitive: if a ‘‘Fishing’’ set already exists, saving a
‘‘fishing’’ set will create a new set instead of overwriting the ‘‘Fishing’’ set.
Arguments:
nameName of the set (string)
iconIndex of an icon to associate with the set: between 1and GetNum
MacroIcons() for an icon from the set of macro icons; values between
-INVSLOT_FIRST_EQUIPPED and -INVSLOT_LAST_EQUIPPED for the icon
of an item in the equipment set at that (negative) inventoryID (number)
SaveView
Saves the current camera settings.
SaveView(index)
There are five ‘‘slots’’ for saved camera settings, indexed 1-5. These views can
be set and accessed directly using SaveView() and SetView(), and cycled
through using NextView() and PrevView().
Arguments:
indexIndex of a saved camera setting (between 1and 5) (number)
Screenshot
Saves an image of the current game display.
Screenshot images are saved to the folder Screenshots within the folder
where the World of Warcraft client is installed.
Taking a screenshot fires the SCREENSHOT_SUCCEEDED event (or the
SCREENSHOT_FAILED event in case of an error), which causes the default UI to
display a message in the middle of the screen. Additional screenshots taken
while this message is displayed will include it. The default UI’s
TakeScreenshot() function hides this message so it is not included in
screenshots.
Blizzard UI SecondsToTime
Returns a description of an amount of time in appropriate units.
time = SecondsToTime(seconds [, noSeconds [, notAbbreviated i
[, maxCount]]])
906 Part IV Reference
Output includes markup normally hidden when displayed in a FontString (see
last example); this markup allows the client to automatically print the singular
or plural form of a word depending on the value of the preceding number.
Arguments:
secondsAn amount of time (in seconds) (number)
noSeconds (optional)True to omit a seconds term in the description; false
or omitted otherwise (boolean)
notAbbreviated (optional)True to use full unit names in the description
(e.g.Hours,Minutes);false or omitted to use abbreviations (e.g. Hr, Min)
(boolean)
maxCount (optional)Maximum number of terms to include in the description;
defaults to 2 if omitted (number)
Returns:
timeA description of the amount of time in appropriate units (see examples)
(string)
Example:
print(SecondsToTime(100))
-- shows “1 Min 40 Sec“
print(SecondsToTime(100, true))
-- shows “1 Min“
print(SecondsToTime(10000))
-- shows “2 Hr 46 Min“
print(SecondsToTime(10000, false, true))
-- shows “2 Hours 46 Minutes“
print(SecondsToTime(100000, false, false, 5))
-- shows “1 Day 3 Hr 46 Min 40 Sec“
SecondsToTime(100, false, true)
-- returns “1 |4Minute:Minutes; 40 |4Second:Seconds;“
SecureCmdOptionParse
Returns the action (and target, if applicable) for a secure macro command.
action, target = SecureCmdOptionParse(“cmd“)
Used in the default UI to parse macro conditionals.
Arguments:
cmdA command to be parsed (typically the body of a macro, macrotext
attribute or slash command (string)
Returns:
actionArgument to the base macro command (e.g. the name of a spell for
/cast), or the empty string (““)ifthebasecommandtakesnoarguments
(e.g. /stopattack); nil if the command should not be executed (string)
targetUnit or name to use as the target of the action (string)
Example:
-- a complex macro command for contextually casting a healing
-- or damage spell
local macroText = “/cast [target=mouseover,harm,nodead][harm,nodead] i
Chapter 27 API Reference 907
Mind Blast ; [target=mouseover,help,nodead,exists] [help,nodead] i
[target=player] Flash Heal“
SecureCmdOptionParse(macroText)
-- returns “Flash Heal“, “player“ if no unit is targeted or moused over
-- returns “Flash Heal“, “mouseover“ if a friendly unit is moused over
-- returns “Flash Heal“ if a friendly unit is targeted
-- returns “Mind Blast“, “mouseover“ if a hostile unit is moused over
-- returns “Mind Blast“ if a hostile unit is targeted
SelectActiveQuest
Selects a quest which can be turned in to the current Quest NPC.
SelectActiveQuest(index)
Usable after a QUEST_GREETING event. Causes the QUEST_PROGRESS event to
fire, in which it is determined whether the player can complete the quest.
Note: Most quest NPCs present active quests using GetGossipActive
Quests() instead of this function.
Arguments:
indexIndex of a quest which can be turned in to the current
Quest NPC (between 1and GetNumActiveQuests())(number)
SelectAvailableQuest
Chooses a quest available from the current Quest NPC.
SelectAvailableQuest(index)
Causes the QUEST_DETAIL event to fire, in which the questgiver presents the
player with the details of a quest and the option to accept or decline.
Note: Most quest NPCs present available quests using
GetGossipAvailableQuests() instead of this function.
Arguments:
indexIndex of a quest available from the current Quest NPC (between 1and
GetNumAvailableQuests())(number)
SelectGossipActiveQuest
Chooses a quest which can be turned in to the current Gossip NPC.
SelectGossipActiveQuest(index)
Causes the QUEST_PROGRESS event to fire, in which it is determined whether
the player can complete the quest.
Arguments:
indexIndex of a quest which can be turned in to the current Gossip
NPC (between 1and GetNumGossipActiveQuests())(number)
SelectGossipAvailableQuest
Chooses a quest available from the current Gossip NPC.
SelectGossipAvailableQuest(index)
908 Part IV Reference
Usable after a QUEST_GREETING event. Causes the QUEST_DETAIL event to fire,
in which the questgiver presents the player with the details of a quest and the
option to accept or decline.
Arguments:
indexIndex of a quest available from the current Gossip NPC
(between 1and GetNumGossipAvailableQuests())(number)
SelectGossipOption
Chooses and activates an NPC dialog option.
SelectGossipOption(index [, “text“ [, confirm]])
Results may vary according to the gossip option chosen; may end the gossip
(firing a GOSSIP_CLOSED event) and start another interaction (firing a
MERCHANT_SHOW,TRAINER_SHOW,TAXIMAP_OPENED, or similar event) or may
continue the gossip with new text and new options (firing another
GOSSIP_SHOW event).
Calling this function with only the first argument may cause the
GOSSIP_CONFIRM event to fire, indicating that the player needs to provide
confirmation (or additional information) before the option will be activated.
Confirmation is needed for certain options requiring the character to spend
(e.g. when activating Dual Talent Specialization); additional information is
needed for options such as those used when redeeming a Loot Card code from
the WoW trading card game to receive an in-game item. In either case, the
confirmation and additional information can be provided (as by the popup
dialog in the default UI) by calling this function again with all three arguments.
Arguments:
indexThe option in the NPC gossip window to select, from 1to GetNumGos-
sipOptions() (number)
text (optional)Text to include when confirming the selection (string)
confirm (optional)true to confirm the selection; false or omitted otherwise
(boolean)
SelectQuestLogEntry
Selects a quest from the quest log.
SelectQuestLogEntry(questIndex)
The selected quest is used by other functions which do not take a quest index
as argument (e.g. GetQuestLogQuestText()).
Arguments:
questIndexIndex of a quest in the quest log (between 1and
GetNumQuestLogEntries())(number)
SelectTradeSkill
Selects a recipe in the trade skill listing.
SelectTradeSkill(index)
Chapter 27 API Reference 909
Selection in the recipe list is used only for display in the default UI and has no
effect on other Trade Skill APIs.
Arguments:
indexIndex of a recipe in the trade skill list (between 1and GetNumTrade
Skills())(number)
SelectTrainerService
Selects an entry in the trainer service listing.
SelectTrainerService(index)
Selection in the service list is used only for display in the default UI and has no
effect on other Trainer APIs.
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
SendAddonMessage
Sends a chat-like message receivable by other addons.
SendAddonMessage(“prefix“, “message“ [, “type“ [, “target“]])
Allows for client-to-client addon communication.
Unlike with SendChatMessage, messages sent via SendAddonMessage:
do not appear in receiving players’ chat windows (unless an addon explicitly
prints them)
are not subject to strict server-side spam filtering/throttling (sending
too many messages at once can still disconnect the user)
are not modified if the sending character is drunk
Messages are received via the CHAT_MSG_ADDON event.
Arguments:
prefixAn arbitrary label for the message. Allows receiving addons to filter
incoming messages: for example, if an addon uses the same prefix for all mes-
sages it sends, an addon interested in only those messages can check for that pre-
fix before handling the message content. Cannot contain the tab character (\t).
(string)
messageA message to send; combined length of prefix and message is lim-
ited to 254 characters (string)
type (optional)Scope in which to broadcast the message: (string)
BATTLEGROUNDTo all allied players in the current battleground instance
GUILDTo all members of the player’s guild
PARTYTo all members of the player’s party (used by default if no type is
given)
RAIDTo all members of the player’s raid group (automatically
reverts to sending to party if the player is not in a raid group)
WHISPERTo a specific player
910 Part IV Reference
target (optional)If type is “WHISPER“, the name of the target player
(in cross-realm battlegrounds, the format ‘‘Name-Realm’’ can be used to
target a player from another realm; e.g. ‘‘Thott-Cenarius’’) (string)
Example:
-- Hypothetical communication using addon messages
local MSG_PREFIX = “MY_MOD“
SendAddonMessage(MSG_PREFIX, “Resync“, “GUILD“)
SendAddonMessage(MSG_PREFIX, “VersionCheck“, “WHISPER“, player)
SendChatMessage
Sends a chat message.
SendChatMessage(“text“ [, “chatType“ [, “language“ [, “channel“]]])
Arguments:
textMessage to be sent (up to 255 characters) (string)
chatType (optional)Channel on which to send the message (defaults to SAY if
omitted) (string)
BATTLEGROUNDMessages to a battleground raid group (sent with /bg in the
default UI)
CHANNELMessage to a server or custom chat channel (sent with /1,/2,
etc in the default UI); requires channel number for channel argument
DNDEnables Away-From-Keyboard status for the player, with text as
the custom message seen by others attempting to whisper the player
EMOTECustom text emotes visible to nearby players (sent with /e in the
default UI)
GUILDMessages to guild members (sent with /g in the default UI)
OFFICERMessages to guild officers (sent with /o in the default UI)
PARTYMessages to party members (sent with /p in the default UI)
RAIDMessages to raid members (sent with /ra in the default UI)
RAID_WARNINGWarning to raid members (sent with /rw in the default UI)
SAYSpeech to nearby players (sent with /s in the default UI)
WHISPERMessage to a specific character (sent with /e in the default
UI); requires name of the character for channel argument
YELLYell to not-so-nearby players (sent with /y in the default UI)
language (optional)Language in which to send the message; defaults to Com-
mon (for Alliance players) or Orcish (for Horde players) if omitted (string)
COMMONAlliance and Human language
DARNASSIANNight Elf Language
DRAENEIDraenei Language
DWARVEN—Dwarf Language
GNOMISHGnome language
GUTTERSPEAKUndead language
ORCISHHorde and Orc Language
Chapter 27 API Reference 911
TAURAHETauren Language
THALASSIANNight Elf Language
TROLLTroll language
channel (optional)If chatType is WHISPER, name of the target character; if
chatType is CHANNEL, number identifying the target channel; ignored otherwise
(string)
Example:
-- Send a chat message to the character the player is currently mousing
-- over. This should be run as a macro (via keybind) so your mouse can
-- be hovering over a unit in the 3-D world, or a unit frame
local name = UnitName(“mouseover“)
SendChatMessage(“Hey “ .. name .. “ I’m mousing over you!!!“, i
“WHISPER“, nil, name)
-- This can be run as a macro by putting it all on one line, and adding
run in front of it, like so:
--
-- /run local name = UnitName(“mouseover“); SendChatMessage(“Hey “ i
.. name .. “ I’m mousing over you!!!“, “WHISPER“, nil, name)
SendMail
Sends the outgoing message.
SendMail(“recipient“, “subject“, “body“)
Any money or COD costs and attachments specified for the message (via
SetSendMailMoney(),SetSendMailCOD(),and
ClickSendMailItemButton()) are included with the message (and the
values for such are reset for the next outgoing message).
Arguments:
recipientName of the character to receive the mail (string)
subjectSubject text of the mail (string)
body—Body text of the mail (string)
SendWho
Requests a list of characters meeting given search criteria from the server.
SendWho(“filter“)
Text in the query will match against any of the six searchable fields unless one
of the specifiers below is used; multiple specifiers can be used in one query.
Queries are case insensitive.
n-“name“Search for characters whose name contains name
c-“class“Search for characters whose class name contains class
g-“guild“Search for characters in guilds whose name contains guild
r-“race“Search for characters whose race name contains race
912 Part IV Reference
z-“zone“Search for characters in zones whose name contains zone
XSearch for characters of level X
X-Search for characters of level Xor higher
-XSearch for characters of level Xor lower
X-YSearch for characters between levels Xand Y(inclusive)
Results are not available immediately; the CHAT_MSG_SYSTEM or
WHO_LIST_UPDATE event fires when data is available, as determined by the
SetWhoToUI() function.
Arguments:
filterA Who system search query (cannot be nil; use the empty string ““
to specify a blank query) (string)
Example:
-- Search for human warriors named Donald in Elwynn Forest
SendWho(’donald z-“elwynn“ r-“human“ c-“warrior“’)
SetAbandonQuest
Begins the process of abandoning a quest in the player’s quest log.
SetAbandonQuest(questIndex)
To finish abandoning the quest, call AbandonQuest().
This function must be called to select a quest in order for
GetAbandonQuestItems() or GetAbandonQuestName() to return valid data.
Arguments:
questIndexIndex of a quest in the quest log (between 1and
GetNumQuestLogEntries())(number)
SetAchievementComparisonUnit
Enables comparing achievements/statistics with another player.
success = SetAchievementComparisonUnit(unit)
After a call to this function, the INSPECT_ACHIEVEMENT_READY event fires to
indicate that achievement/statistic comparison functions will return valid data
on the given unit.
Arguments:
unitID of a unit to compare against (unitID)
Returns:
success1if the given unit is a valid unit. (Does not indicate
whether the unit exists or can be compared against.) (1nil)
SetActionBarToggles
Configures display of additional ActionBars in the default UI.
SetActionBarToggles(bar1, bar2, bar3, bar4, alwaysShow)
Arguments:
bar11to show the bottom left ActionBar; otherwise nil (1nil)
bar21to show the bottom right ActionBar; otherwise nil (1nil)
Chapter 27 API Reference 913
bar31to show the right-side ActionBar; otherwise nil (1nil)
bar41to show the second right-side ActionBar; otherwise nil (1nil)
alwaysShow1to always show ActionBar backgrounds even for empty slots;
otherwise nil (1nil)
SetActiveTalentGroup
Switches the player’s active talent specialization.
SetActiveTalentGroup(talentGroup)
Calling this function with the index of an inactive talent group does not
immediately perform the switch: it begins casting a spell (‘‘Activate Primary/
Secondary Spec’’), and only once the spellcast is complete are the player’s
talents changed.
Calling this function with the index of the active talent group, or with any
argument if the player has not purchased Dual Talent Specialization, does
nothing.
Arguments:
talentGroupIndex of the talent specialization to enable (number)
SetActiveVoiceChannel
Sets the currently active voice channel.
SetActiveVoiceChannel(index)
Arguments:
indexIndex of a channel in the chat display window (between 1and
GetNumDisplayChannels())(number)
SetActiveVoiceChannelBySessionID
Sets the currently active voice chat channel.
SetActiveVoiceChannelBySessionID(session)
Arguments:
sessionIndex of a voice session (between 1and GetNumVoiceSessions())
(number)
SetArenaTeamRosterSelection
Selects a member in an arena team roster.
SetArenaTeamRosterSelection(team, index)
Selection in the arena team roster currently has no effect beyond highlighting
list entry in the default UI.
Arguments:
teamIndex of one of the player’s arena teams (number,arenaTeamID)
indexIndex of a team member to select (between 1and GetNumArenaTeam
Members(team))(number)
SetBagPortraitTexture
Sets a Texture object to display the icon of one of the player’s bags.
SetBagPortraitTexture(texture, container)
914 Part IV Reference
Adapts the square item icon texture to fit within the circular ‘‘portrait’’ frames
used in many default UI elements.
Arguments:
texture—A Texture object (table)
containerIndex of one of the player’s bags or other containers (number,con-
tainerID)
Example:
-- Set a texture to the rounded icon of the player’s first
-- bag (not the backpack)
SetBagPortraitTexture(MyBagTexture, 1)
SetBattlefieldScoreFaction
Filters the battleground scoreboard by faction/team.
SetBattlefieldScoreFaction(faction)
Arguments:
factionFaction for which to show battleground participant scores (number)
0—Horde
1Alliance
nil—All
SetBinding
Binds a key combination to a binding command.
success = SetBinding(“key“ [, “command“])
Arguments:
keyA key or key combination (e.g. ‘‘CTRL-2’’) (string,binding)
command (optional)Name of a key binding command, or nil to unbind the
key (string)
Returns:
success1if the key binding (or unbinding) was successful; otherwise nil
(1nil)
Example:
-- Bind Control-Y to FOLLOWTARGET
SetBinding(“CTRL-Y“, “FOLLOWTARGET“)
-- Unbind MouseButton4
SetBinding(“BUTTON4“)
SetBindingClick
Binds a key combination to ‘‘click’’ a Button object.
success = SetBindingClick(“key“, “buttonName“ [, “mouseButton“])
When the binding is used, all of the relevant mouse handlers on the button
(save for OnEnter and OnLeave) fire just as if the button were activated by the
mouse (including OnMouseDown and OnMouseUp as the key is pressed and
released).
Chapter 27 API Reference 915
Arguments:
keyA key or key combination (e.g. ‘‘CTRL-2’’) (string,binding)
buttonNameName of a Button object on which the binding simulates a click
(string)
mouseButton (optional)Name of the mouse button with which the binding
simulates a click (string)
Returns:
success1if the key binding was successful; otherwise nil (1nil)
SetBindingItem
Binds a key combination to use an item in the player’s possession.
success = SetBindingItem(“key“, itemID) or SetBindingItem(“key“, i
“itemName“) or SetBindingItem(“key“, “itemLink“)
Arguments:
keyA key or key combination (e.g. ‘‘CTRL-2’’) (string,binding)
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Returns:
success1if the binding was successful; otherwise nil (1nil)
SetBindingMacro
Binds a key combination to run a macro.
success = SetBindingMacro(“key“, index) or i
SetBindingMacro(“key“, “name“)
Arguments:
keyA key or key combination (e.g. ‘‘CTRL-2’’) (string,binding)
index—Index of a macro (number,macroID)
name—Name of a macro (string)
Returns:
success1if the key binding was successful; otherwise nil (1nil)
SetBindingSpell
Binds a key combination to cast a spell.
success = SetBindingSpell(“key“, “spellname“)
Arguments:
keyA key or key combination (e.g. ‘‘CTRL-2’’) (string,binding)
spellnameName of a spell to bind (string)
Returns:
success1if the key binding was successful; otherwise nil (1nil)
Example:
-- Bind Flash Heal to ALT-Y
SetBindingSpell(“ALT-Y“, “Flash Heal“)
916 Part IV Reference
SetCVar
Sets the value of a configuration variable.
SetCVar(“cvar“, value [, “raiseEvent“])
Arguments:
cvarName of the CVar to set (string)
valueNew value for the CVar (any)
raiseEvent (optional)If true, causes the CVAR_UPDATE event to fire (string)
SetChannelOwner
Gives channel ownership to another character.
SetChannelOwner(“channel“, “fullname“)
Has no effect unless the player is the owner of the given channel.
Arguments:
channelName of the channel (string)
fullnameName of the character to make the new owner (string)
Example:
-- Give “Cladhaire“ ownership in the channel “monkeys“
SetChannelOwner(“monkeys“, “Cladhaire“)
SetChannelPassword
Sets a password on a custom chat channel.
SetChannelPassword(“channel“, “password“)
Arguments:
channelName of the channel (string)
passwordPassword to set for the channel (string)
SetChatWindowAlpha
Saves a chat window’s background opacity setting.
SetChatWindowAlpha(index, alpha)
Used by the default UI’s function FCF_SetWindowAlpha() which changes the
opacity of a displayed FloatingChatFrame.
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
alphaAlpha value (opacity) of the chat window background (0 =fully trans-
parent, 1=fully opaque) (number)
SetChatWindowColor
Saves a chat window’s background color setting.
SetChatWindowColor(index, r, g, b)
Used by the default UI’s function FCF_SetWindowColor() which changes the
colors of a displayed FloatingChatFrame.
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
Chapter 27 API Reference 917
rRed component of the background color (0.0 - 1.0) (number)
gGreen component of the background color (0.0 - 1.0) (number)
bBlue component of the background color (0.0 - 1.0) (number)
SetChatWindowDocked
Saves whether a chat window should be docked with the main chat window.
SetChatWindowDocked(index, docked)
Used by the default UI’s functions FCF_DockFrame() and
FCF_UnDockFrame() which manage the positioning of FloatingChatFrames.
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
dockedTrue if the window should be docked with the main chat window;
otherwise false (boolean)
SetChatWindowLocked
Saves whether a chat window is locked.
SetChatWindowLocked(index, locked)
Used by the default UI’s functions FCF_OpenNewWindow() and
FCF_SetLocked() which manage the behavior of a FloatingChatFrame.
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
lockedTrue if the frame should be locked; otherwise false (boolean)
SetChatWindowName
Saves a chat window’s display name setting.
SetChatWindowName(index, “name“)
Used by the default UI’s function FCF_SetWindowName() which also handles
setting the name displayed for a FloatingChatFrame.
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
nameName to be displayed for the chat window (string)
SetChatWindowShown
Saves whether a chat window should be shown.
SetChatWindowShown(index, shown)
Used by the default UI’s function FCF_OpenNewWindow() which initializes a
displayed FloatingChatFrame.
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
shownTrue if the window should be shown, false otherwise (boolean)
SetChatWindowSize
Saves a chat window’s font size setting.
SetChatWindowSize(index, size)
918 Part IV Reference
Used by the default UI’s function FCF_SetChatWindowFontSize() which
also handles changing the font displayed in a FloatingChatFrame.
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)
(number)
sizeFont size for the chat window (in points) (number)
SetChatWindowUninteractable
Saves whether a chat window is marked as non-interactive.
SetChatWindowUninteractable(index, setUninteractable)
Used by the default UI’s function FCF_SetUninteractable() which also
handles enabling/disabling mouse events in the FloatingChatFrame.
Arguments:
indexIndex of a chat frame (between 1and NUM_CHAT_WINDOWS)(number)
setUninteractableTrue flags the window as non-interactive; false other-
wise (boolean)
SetCurrencyBackpack
SetsacurrencytypetobewatchedontheBackpackUI.
SetCurrencyBackpack(index, watch)
Arguments:
indexIndex of a currency type or header in the currency list (between 1and
GetCurrencyListSize()) (number)
watch1to add this currency to the backpack UI; 0 to remove it from being
watched (number)
SetCurrencyUnused
Moves a currency type to or from the Unused currencies list.
SetCurrencyUnused(index, makeUnused)
‘‘Unused’’ currencies behave no differently; the distinction only exists to allow
players to hide currencies they don’t care about from the main display.
Arguments:
indexIndex of a currency type or header in the currency list (between 1and
GetCurrencyListSize()) (number)
makeUnused1to move this currency to the Unused category; 0 to return it to
its original category (number)
SetCurrentGuildBankTab
Selects a tab in the guild bank.
SetCurrentGuildBankTab(tab)
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
Chapter 27 API Reference 919
SetCurrentTitle
Changes a player’s displayed title.
SetCurrentTitle(titleIndex)
Arguments:
titleIndexIndex of a title available to the player (between 1and
GetNumTitles()), or -1to show no title (integer)
SetCursor
Changes the mouse cursor image.
SetCursor(“cursor“)
Changes only the appearance of the mouse cursor, not its behavior (and has no
effect if the cursor is holding an item, spell, or other data). Passing nil will
revert the cursor to its default image.
Normally used in a frame’s OnEnter handler to change the cursor used while
the mouse is over the frame. If used elsewhere, the cursor will likely be
immediately reverted to default (due to the mouse handlers of other frames
doing the same).
Arguments:
cursorPath to a texture to use as the cursor image (must be 32x32 pixels) or
one of the built-in cursor tokens. Valid cursor tokens can be found in the example
code. (string)
Example:
-- Creates a button in the center of the screen which can be moused over
-- repeatedly to show all of the available cursors
local cursors = { “NORMAL_CURSOR“, “ATTACK_CURSOR“, i
“ATTACK_ERROR_CURSOR“, “BUY_CURSOR“, “BUY_ERROR_CURSOR“, i
“CAST_CURSOR“, “CAST_ERROR_CURSOR“, “GATHER_CURSOR“, i
“GATHER_ERROR_CURSOR“, “INNKEEPER_CURSOR“, i
“INNKEEPER_ERROR_CURSOR“, “INSPECT_CURSOR“, i
“INSPECT_ERROR_CURSOR“, “INTERACT_CURSOR“, “INTERACT_ERROR_CURSOR“, i
“ITEM_CURSOR“, “ITEM_ERROR_CURSOR“, “LOCK_CURSOR“, i
“LOCK_ERROR_CURSOR“, “LOOT_ALL_CURSOR“, “LOOT_ALL_ERROR_CURSOR“, i
“MAIL_CURSOR“, “MAIL_ERROR_CURSOR“, “MINE_CURSOR“, i
“MINE_ERROR_CURSOR“, “PICKUP_CURSOR“, “PICKUP_ERROR_CURSOR“, i
“POINT_CURSOR“, “POINT_ERROR_CURSOR“, “QUEST_CURSOR“, i
“QUEST_ERROR_CURSOR“, “REPAIRNPC_CURSOR“, “REPAIRNPC_ERROR_CURSOR“, i
“REPAIR_CURSOR“, “REPAIR_ERROR_CURSOR“, “SKIN_ALLIANCE_CURSOR“, i
“SKIN_ALLIANCE_ERROR_CURSOR“, “SKIN_CURSOR“, “SKIN_ERROR_CURSOR“, i
“SKIN_HORDE_CURSOR“, “SKIN_HORDE_ERROR_CURSOR“, “SPEAK_CURSOR“, i
“SPEAK_ERROR_CURSOR“, “TAXI_CURSOR“, “TAXI_ERROR_CURSOR“, i
“TRAINER_CURSOR“, “TRAINER_ERROR_CURSOR“ }
local current = 0
CreateFrame(“Button“, “CursorTestFrame“, UIParent, i
“GameMenuButtonTemplate“)
920 Part IV Reference
CursorTestFrame:SetPoint(“CENTER“, 0, 0)
CursorTestFrame:SetText(“Hover to change cursor“)
local function OnEnter(self) current = current + 1
if current > #cursors then
current = 1
end
SetCursor(cursors[current])
self:SetText(cursors[current])
end
CursorTestFrame:SetScript(“OnEnter“, OnEnter)
SetDungeonDifficulty
SetDungeonDifficulty
Sets the player’s 5 player dungeon difficulty preference.
SetDungeonDifficulty(difficulty)
Setting dungeon difficulty has no effect on the instance created when entering
a portal if the player is not the party/raid leader. Changing difficulty while in
an instance also has no effect.
Epic difficulty is currently unused; setting dungeon difficulty to 3 will cause
instance portal graphics to disappear and may result in errors upon entering
an instance portal.
Arguments:
difficultyA difficulty level (number)
1—5 Player (Normal)
25 Player (Heroic)
SetDungeonMapLevel
Sets the world map to display a certain map image (for zones that use multiple
map images).
SetDungeonMapLevel(level)
Used in zones with more than one ‘‘floor’’ or area such as Dalaran and several
Wrath of the Lich King dungeons and raids.
Arguments:
levelIndex of the map image to show in the world map (number)
SetEuropeanNumbers
Sets the decimal separator for displayed numbers.
SetEuropeanNumbers(enable)
Affects the style not only of numbers displayed in the UI, but any string
coercion of numbers with tostring() as well.
Arguments:
enableTrue to use comma (‘‘,’’) as the decimal separator; false to use period
(‘‘.’’) as the decimal separator (boolean)
Chapter 27 API Reference 921
SetFactionActive
Removes the ‘‘inactive’’ status from a faction.
SetFactionActive(index)
‘‘Inactive’’ factions behave no differently; the distinction only exists to allow
players to hide factions they don’t care about from the main display. Factions
thus marked are automatically moved to an ‘‘Inactive’’ group at the end of the
faction list.
Arguments:
indexIndex of an entry in the faction list; between 1and GetNumFactions()
(number)
SetFactionInactive
Flags a faction as inactive.
SetFactionInactive(index)
‘‘Inactive’’ factions behave no differently; the distinction only exists to allow
players to hide factions they don’t care about from the main display. Factions
thus marked are automatically moved to an ‘‘Inactive’’ group at the end of the
faction list.
Arguments:
indexIndex of an entry in the faction list; between 1and GetNumFactions()
(number)
SetFriendNotes
Sets note text associated with a friends list entry.
SetFriendNotes(index, “note“) or SetFriendNotes(“name“, “note“)
Setting a note to nil will result in an error; to remove a note, set it to the empty
string (““).
Arguments:
indexIndex of a friends list entry (between 1and GetNumFriends())
(number)
name—Name of friend to modify (string)
noteThe note to set (string)
SetGamma
Changes the display gamma setting.
SetGamma(value)
Gamma value determines the contrast between lighter and darker portions of
the game display; for a detailed explanation see the Wikipedia article on
Gamma correction.
Arguments:
valueNew gamma value (number)
SetGuildBankTabInfo
Sets the name and icon for a guild bank tab.
SetGuildBankTabInfo(tab, “name“, iconIndex)
922 Part IV Reference
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
nameNew name for the tab (string)
iconIndexIndex of an icon for the tab (between 1and GetNumMacroItem
Icons())(number)
SetGuildBankTabPermissions
Changes guild bank tab permissions for the guild rank being edited.
SetGuildBankTabPermissions(tab, permission, enabled)
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
permissionIndex of a permission to edit (number)
1—View tab
2Deposit items
enabledTrue to allow permission for the action to the guild rank; false to
deny (boolean)
SetGuildBankTabWithdraw
Sets the number of item withdrawals allowed per day for the guild rank being
edited.
SetGuildBankTabWithdraw(tab, amount)
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
amountMaximum number of item (stack) withdrawals allowed per day for the
guild rank (number)
SetGuildBankText
Sets the info text for a guild bank tab.
SetGuildBankText(tab, “text“)
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBankTabs())
(number)
textNew info text for the tab (string)
SetGuildBankWithdrawLimit
Sets the maximum amount of money withdrawals per day allowed for the
guild rank being edited.
SetGuildBankWithdrawLimit(amount)
Arguments:
amountMaximum amount of money allowed to be withdrawn per day for the
guild rank (in copper) (number)
Chapter 27 API Reference 923
SetGuildInfoText
Sets the guild information text.
SetGuildInfoText(“text“)
This text appears when clicking the ‘‘Guild Information’’ button in the default
UI’s Guild window.
Arguments:
textNew guild information text (string)
SetGuildRosterSelection
Selects a member in the guild roster.
SetGuildRosterSelection(index)
Selection in the guild roster is used only for display in the default UI and has
no effect on other Guild APIs.
Arguments:
indexIndex of a member in the guild roster (between 1and
GetNumGuildMembers()), or 0 for no selection (number)
SetGuildRosterShowOffline
Enables or disables inclusion of offline members in the guild roster listing.
SetGuildRosterShowOffline(showOffline)
Arguments:
showOfflineTrue to include offline members in the guild roster
listing; false to list only those members currently online (boolean)
SetInventoryPortraitTexture
Sets a Texture object to display the icon of an equipped item.
SetInventoryPortraitTexture(texture, “unit“, slot)
Adapts the square item icon texture to fit within the circular ‘‘portrait’’ frames
used in many default UI elements.
Arguments:
texture—A Texture object (table)
unitA unit whose item should be displayed; only valid for player (string,
unitID)
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
SetLFGAutojoin
Enables the option to automatically join a group matching current LFG criteria.
SetLFGComment
Associates a brief text comment with the player’s listing in the LFG system.
SetLFGComment(“comment“)
In the default UI, other players see this comment when mousing over the
player’s name in the Looking for More listing.
924 Part IV Reference
Arguments:
commentA comment to be associated with the player’s listing in the
LFG system (max 63 characters); or the empty string (““) to clear an existing
comment (string)
Example:
-- Sets the player’s LFG comment to a quick summary of talent spec
-- (If already participating in the LFG UI)
local _, _, tab1Points = GetTalentTabInfo(1)
local _, _, tab2Points = GetTalentTabInfo(2)
local _, _, tab3Points = GetTalentTabInfo(3)
SetLFGComment(tab1Points..“/“..tab2Points..“/“..tab3Points)
SetLFGRoles
Sets group roles for which to advertise the player in the LFG system.
SetLFGRoles(leader, tank, healer, damage)
Passing true for a role the player’s class does not support (e.g. healing on a
warrior or tanking on a priest) has no effect: see example.
Arguments:
leaderTrue if the player is willing to lead a group; otherwise false
(boolean)
tankTrue if the player is willing to take on the role of protecting
allies by drawing enemy attacks; otherwise false (boolean)
healerTrue if the player is willing to take on the role of healing allies who
take damage; otherwise false (boolean)
damageTrue if the player is willing to take on the role of damaging enemies;
otherwise false (boolean)
Example:
SetLFGRoles(true,true,true,true)
GetLFGRoles()
-- on a priest: returns true,false,true,true
-- on a warrior: returns true,true,false,true
SetLFMAutofill
Enables the option to automatically fill the player’s group when Looking for
More.
SetLFMType
Sets the type for LFM queries.
SetLFMType(type)
Does not actually send a query; used in the default UI to allow query
parameters to be saved and reused across UI restarts. See LFGQuery() for
actual queries.
Arguments:
typeIndex of an LFG query type (in the list returned by GetLFGTypes())
(number)
Chapter 27 API Reference 925
SetLookingForGroup
Adds the player to the LFG system for one of three objectives.
SetLookingForGroup(slot, type, index)
Players are currently allowed to set up to three objectives to be advertised in
the LFG system.
Arguments:
slotIndex of an LFG objective (between 1and 3) (number)
typeIndex of an LFG query type (in the list returned by GetLFGTypes())
(number)
indexIndex of an LFG entry (in the list returned by GetLFGTypeEntries
(type))(number)
SetLookingForMore
Sets up a Looking for More query.
SetLookingForMore(type, index)
Does not actually send a query; used in the default UI to allow query
parameters to be saved and reused across UI restarts. See LFGQuery() for
actual queries.
Arguments:
typeIndex of an LFG query type (in the list returned by GetLFGTypes())
(number)
indexIndex of an LFG entry (in the list returned by GetLFGTypeEntries
(type))(number)
SetLootMethod
Sets the loot method for a party or raid group.
SetLootMethod(“method“ [, “master“])
Has no effect if the player is not the party or raid leader.
See SetLootThreshold for the quality threshold used by Master Looter,
Group Loot, and Need Before Greed methods.
Arguments:
methodMethod to use for loot distribution (string)
freeforallFree for All; any group member can take any loot at any time
groupGroup Loot; like Round Robin, but items above a quality threshold
are rolled on
masterMaster Looter; like Round Robin, but items above a
quality threshold are left for a designated loot master to
needbeforegreedNeed before Greed; like Group Loot, but members auto-
matically pass on items
roundrobinRound Robin; group members take turns being able to loot
master (optional)Name or unitID of the master looter (string)
926 Part IV Reference
SetLootPortrait
Sets a Texture object to show the appropriate portrait image when looting.
SetLootPortrait(texture)
Normally, the loot portrait image is the same as that of the creature being
looted. Not used in the default UIa generic image for all loot is used instead.
Arguments:
texture—A Texture object (table)
SetLootThreshold
Sets the threshold used for Master Looter, Group Loot, and Need Before Greed
loot methods.
SetLootThreshold(threshold)
Has no effect if the player is not the party or raid leader.
Items above the threshold quality will trigger the special behavior of the
current loot method: for Group Loot and Need Before Greed, rolling will
automatically begin once a group member loots the corpse or object holding
the item; for Master Loot, the item will be invisible to all but the loot master
tasked with assigning the loot.
The loot threshold defaults to 2(Uncommon) when forming a new party/raid.
Setting the threshold to 0(Poor) or 1(Common) has no effectqualities below
Uncommon are always treated as below the threshold. The default UI only
allows setting the threshold as high as 4(Epic), but higher thresholds are
allowed.
Arguments:
thresholdMinimum item quality to trigger the loot method (number,
itemQuality)
SetMacroItem
Changes the item used for dynamic feedback for a macro.
SetMacroItem(index, “item“ [, target]) or i
SetMacroItem(“name“, “item“ [, target])
Normally a macro uses the item or spell specified by its commands to provide
dynamic feedback when placed on an action button (through the Action APIs,
e.g. IsActionUsable()): e.g. if the macro uses a consumable item, the button
will show the number of items remaining; if the macro uses an item with a
cooldown, the button will show the state of the cooldown. This function allows
overriding the item or spell used by the macro with another item. The given
item’s state will be used for such feedback instead of the item or spell used by
the macro.
Arguments:
index—Index of a macro (number,macroID)
name—Name of a macro (string)
itemName of an item to use for the macro (string)
target (optional)A unit to use as target of the item (affects the macro’s range
indicator) (unitid)
Chapter 27 API Reference 927
Example:
-- Create a macro and note the index (19 - 36 are the character
-- specific indices)
-- Target a friendly item that you can bandage
-- Set the first argument to the macro index
-- Set the second argument to the name of a a bandage you have
-- in your inventory
SetMacroItem(19, “Heavy Runecloth Bandage“, “target“)
-- The given macro on your action bars should now use the bandage range
-- to indicate whether or not the macro is “in range“
SetMacroSpell
Changes the spell used for dynamic feedback for a macro.
SetMacroSpell(index, “spell“ [, target]) or i
SetMacroSpell(“name“, “spell“ [, target])
Normally a macro uses the item or spell specified by its commands to provide
dynamic feedback when placed on an action button (through the Action APIs,
e.g. IsActionUsable()): e.g. if the macro uses a consumable item, the button
will show the number of items remaining; if the macro uses an item with a
cooldown, the button will show the state of the cooldown. This function allows
overriding the item or spell used by the macro with another item. The given
item’s state will be used for such feedback instead of the item or spell used by
the macro.
Arguments:
index—Index of a macro (number,macroID)
name—Name of a macro (string)
spellName of a spell to use for the macro (string)
target (optional)A unit to use as target of the spell (affects the macro’s range
indicator) (unitid)
SetMapToCurrentZone
Sets the world map to show the zone in which the player is located.
SetMapZoom
Sets the world map to show a specific zone or continent.
SetMapZoom(continentIndex [, zoneIndex])
Arguments:
continentIndexIndex of a continent to display (in the list returned
by GetMapContinents(), or one of the following values) (number)
-1—Cosmic map
0—Entire Azeroth map
1Kalimdor
2Eastern Kingdoms
3—Outland
4—Northrend
zoneIndex (optional)Index of a zone within the continent to display (in the
list returned by GetMapZones(continentIndex)), or omitted to show the con-
tinent map (number)
928 Part IV Reference
Example:
-- show the cosmic map
SetMapZoom( -1 )
-- show all the azeroth continents
SetMapZoom( 0 )
-- show the outland continent
SetMapZoom( 3 )
-- show dun morogh
SetMapZoom( 2, 7)
SetModifiedClick
Sets a modified click for a given action.
SetModifiedClick(“action“, “binding“)
Arguments:
actionToken identifying the modified click action (string)
bindingThe set of modifiers (and mouse button, if applicable) to register for
the action (string,binding)
SetMouselookOverrideBinding
Overrides the default mouselook bindings to perform another binding with the
mouse buttons.
SetMouselookOverrideBinding(“key“, “binding“)
Arguments:
keyThe mouselook key to override (string)
BUTTON1Override the left mouse button
BUTTON2Override the right mouse button
bindingThe binding to perform instead of mouselooking, or nil to clear the
override (string)
Example:
-- Uses the 'z' button to activate mouselook instead of the mouse
-- buttons, and the mouse buttons to move forward and backward
-- instead of mouselooking.
-- Credits to slouken for this code.
CreateFrame(“Button“, “MouselookButton“)
MouselookButton:RegisterForClicks(“AnyUp“, “AnyDown“)
MouselookButton:SetScript(“OnClick“, function (self, button, down)
if ( down ) then
MouselookStart()
else
MouselookStop()
end
end)
SetOverrideBindingClick(MouselookButton, nil, “Z“, “MouselookButton“)
SetMouselookOverrideBinding(“BUTTON1“, “MOVEFORWARD“)
SetMouselookOverrideBinding(“BUTTON2“, “MOVEBACKWARD“)
Chapter 27 API Reference 929
SetMultiCastSpell
Sets a multi-cast action slot to a given spell.
SetMultiCastSpell(action, spell)
This function is used to set up the multi-cast action slots, such as the totem bar
that was introduced with WoW 3.2. The player is able to customize three
different sets of totems that can then be cast with a single click.
Arguments:
actionThe multi-cast action slot to set (number)
spellThe numeric spellId to set to the given action slot (number)
SetMultisampleFormat
Changes the multisample setting.
SetMultisampleFormat(index)
The index argument corresponds to the individual settings described by
GetMultisampleFormats() (each a set of three values).
Arguments:
indexIndex of a multisample setting (number)
SetNextBarberShopStyle
Selects the next style for a barber shop style option.
SetNextBarberShopStyle(styleIndex [, reverse])
Changes the underlying data (and thus the character’s appearance) only; the
default barbershop UI does not update.
Arguments:
styleIndexIndex of a style option (number)
1—Hair (or Horn) Style
2Hair (or Horn) Color
3Varies by race and gender: Facial Hair, Earrings, Features, Hair, Horns,
Markings, Normal, Piercings, or Tusks
reverse (optional)True to select the previous style; false or omitted to
select the next (boolean)
SetOptOutOfLoot
Changes the player’s preference to opt out of loot rolls.
SetOptOutOfLoot(enable)
When opting out, no prompt will be shown for loot which ordinarily would
prompt the player to roll (need/greed) or pass; the loot rolling process will
continue for other group members as if the player had chosen to pass on
every roll.
Arguments:
enableTrue to opt out of loot, false to participate in loot rolls (boolean)
SetOverrideBinding
Sets an override binding for a binding command.
SetOverrideBinding(owner, isPriority, “key“, “command“)
930 Part IV Reference
Override bindings are temporary. The bound key will revert to its normal
setting once the override is removed. Priority overrides work the same way but
will revert to the previous override binding (if present) rather than the base
binding for the key.
Call with a fourth argument of nil to remove the override binding for a
specific key, or see ClearOverrideBindings() to remove all bindings
associated with a given owner.
Arguments:
ownerThe Frame (or other widget) object responsible for this override (table)
isPriorityTrue if this binding takes higher priority than other override
bindings; false otherwise (boolean)
keyA key or key combination (e.g. ‘‘CTRL-2’’) (string,binding)
commandName of a key binding command, or nil to remove the override
binding (string)
SetOverrideBindingClick
Sets an override binding to ‘‘click’’ a Button object.
SetOverrideBindingClick(owner, isPriority, “key“, i
“buttonName“ [, “mouseButton“])
Override bindings are temporary. The bound key will revert to its normal
setting once the override is removed. Priority overrides work the same way but
will revert to the previous override binding (if present) rather than the base
binding for the key.
Call with a fourth argument of nil to remove the override binding for a
specific key, or see ClearOverrideBindings() to remove all bindings
associated with a given owner.
Arguments:
ownerThe Frame (or other widget) object responsible for this override (table)
isPriorityTrue if this binding takes higher priority than other override
bindings; false otherwise (boolean)
keyA key or key combination (e.g. ‘‘CTRL-2’’) (string,binding)
buttonNameName of a Button object on which the binding simulates a click
(string)
mouseButton (optional)Name of the mouse button with which the binding
simulates a click (string)
SetOverrideBindingItem
Sets an override binding to use an item in the player’s possession.
SetOverrideBindingItem(owner, isPriority, “key“, itemID) or i
SetOverrideBindingItem(owner, isPriority, “key“, “itemName“) or i
SetOverrideBindingItem(owner, isPriority, “key“, “itemLink“)
Override bindings are temporary. The bound key will revert to its normal
setting once the override is removed. Priority overrides work the same way but
will revert to the previous override binding (if present) rather than the base
binding for the key.
Chapter 27 API Reference 931
Call with a fourth argument of nil to remove the override binding for a
specific key, or see ClearOverrideBindings() to remove all bindings
associated with a given owner.
Arguments:
ownerThe Frame (or other widget) object responsible for this override (table)
isPriorityTrue if this binding takes higher priority than other override
bindings; false otherwise (boolean)
keyA key or key combination (e.g. ‘‘CTRL-2’’) (string,binding)
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
SetOverrideBindingMacro
Sets an override binding to run a macro.
SetOverrideBindingMacro(owner, isPriority, “key“, index) or i
SetOverrideBindingMacro(owner, isPriority, “key“, “name“)
Override bindings are temporary. The bound key will revert to its normal
setting once the override is removed. Priority overrides work the same way but
will revert to the previous override binding (if present) rather than the base
binding for the key.
Call with a fourth argument of nil to remove the override binding for a
specific key, or see ClearOverrideBindings() to remove all bindings
associated with a given owner.
Arguments:
ownerThe Frame (or other widget) object responsible for this override (table)
isPriorityTrue if this binding takes higher priority than other override
bindings; false otherwise (boolean)
keyA key or key combination (e.g. ‘‘CTRL-2’’) (string,binding)
index—Index of a macro (number,macroID)
name—Name of a macro (string)
SetOverrideBindingSpell
Set an override binding to a specific spell.
SetOverrideBindingSpell(owner, isPriority, “key“, “spellname“)
Override bindings are temporary. The bound key will revert to its normal
setting once the override is removed. Priority overrides work the same way but
will revert to the previous override binding (if present) rather than the base
binding for the key. See ClearOverrideBindings() to remove bindings
associated with a given owner.
Arguments:
ownerThe Frame (or other widget) object responsible for this override (table)
isPriorityTrue if this binding takes higher priority than other override
bindings; false otherwise (boolean)
932 Part IV Reference
keyA key or key combination (e.g. ‘‘CTRL-2’’) (string,binding)
spellnameName of a spell, or nil to remove the override binding (string)
Example:
-- Set up Shift-2 to cast Prayer of Mending as an override binding
-- owned by PlayerFrame
SetOverrideBindingSpell(PlayerFrame, 1, “SHIFT-2“, “Prayer of Mending“)
-- Clear PlayerFrame’s override bindings
ClearOverrideBindings(PlayerFrame)
SetPVP
Enables or disables the player’s desired PvP status.
SetPVP(state)
Enabling PvP takes effect immediately; disabling PvP begins a five-minute
countdown after which PvP status will be disabled (if the player has taken no
PvP actions).
Arguments:
state1to enable PVP, nil to disable (1nil)
Protected SetPartyAssignment
Assigns a group role to a member of the player’s party or raid.
SetPartyAssignment(“assignment“, “unit“) or i
SetPartyAssignment(“assignment“, “name“ [, exactMatch])
Arguments:
assignmentA group role to assign to the unit (string)
MAINASSISTAssign the main assist role
MAINTANKAssign the main tank role
unitA unit in the player’s party or raid (string,unitID)
nameName of a unit in the player’s party or raid (string)
exactMatch (optional)True to check only units whose name exactly
matches the name given; false to allow partial matches (boolean)
SetPetStablePaperdoll
Sets the given Model to show the selected stabled pet.
SetPetStablePaperdoll(model)
Arguments:
model—A Model frame (table)
Example:
-- Open the character window and the pet stable before running this code
-- Changes the character model to the pet model
SetPetStablePaperdoll(CharacterModelFrame)
SetPortraitTexture
Sets a Texture object to show a portrait of a unit.
SetPortraitTexture(texture, “unit“)
Chapter 27 API Reference 933
Causes the client to render a view of the unit’s model from a standard
perspective into a circular 2D image and display it in the given Texture object.
Arguments:
texture—A Texture object (table)
unitA unit for which to display a portrait (string,unitID)
SetPortraitToTexture
Sets a Texture object to display an arbitrary texture, altering it to fit a circular
frame.
SetPortraitToTexture(“frameName“, “texturePath“)
Used in the default UI to display square textures (such as item icons) within
the circular ‘‘portrait’’ frames used in many default UI elements.
Arguments:
frameName—Name of a Texture object (string)
texturePathPathtoatexturetodisplay(string)
Example:
-- Change the player portrait to be the same as the keychain portrait
SetPortraitToTexture(“PlayerPortrait“, i
“Interface\\ContainerFrame\\KeyRing-Bag-Icon“)
-- Set the player portrait to be the icon for “Staff
-- of Infinite Mysteries“
SetPortraitToTexture(“PlayerPortrait“, i
“Interface\\Icons\\INV_Weapon_Halberd17“)
SetRaidDifficulty
Sets the player’s raid dungeon difficulty preference.
SetRaidDifficulty(difficulty)
The dungeon difficulty has no effect on the instance created if the player is not
the raid leader or while you are inside an instance already.
Arguments:
difficultyDifficulty level for raid dungeons
1—10 Player
2—25 Player
310 Player (Heroic)
425 Player (Heroic)
SetRaidRosterSelection
Selects a unit in the raid roster.
SetRaidRosterSelection(index)
Selection in the raid roster is used only for display in the default UI and has no
effect on other Raid APIs.
Arguments:
indexIndex of the raid member (between 1and GetNumRaidMembers());
matches the numeric part of the unit’s raid unitID,e.g.21 for raid21 (number)
934 Part IV Reference
SetRaidSubgroup
Moves a raid member to a non-full raid subgroup.
SetRaidSubgroup(index, subgroup)
Only has effect if the player is the raid leader or a raid assistant. To put a
member into a full subgroup (switching places with a member of that group),
see SwapRaidSubgroup().
Arguments:
indexIndex of the raid member (between 1and GetNumRaidMembers());
matches the numeric part of the unit’s raid unitID,e.g.21 for raid21 (number)
subgroupIndex of a raid subgroup (between 1and MAX_RAID_GROUPS)
(number)
SetRaidTarget
Puts a raid target marker on a unit.
SetRaidTarget(“unit“, index) or SetRaidTarget(“name“, index)
Arguments:
unit—A unit to mark (string,unitID)
name—Name of a unit to mark (string)
indexIndex of a target marker (number)
0Clear any raid target markers
1—Star
2—Circle
3—Diamond
4—Triangle
5Moon
6—Square
7—Cross
8—Skull
SetScreenResolution
Changes the screen resolution.
SetScreenResolution(index)
Arguments:
indexIndex of a resolution setting (between 1and select(“#“,
GetScreenResolutions()))(number)
Example:
-- Print the possible resolutions to ChatFrame1
-- These indices can then be used in SetScreenResolution()
local resolutions = {GetScreenResolutions()}
for idx,resolution in ipairs(resolutions) do
print(“Resolution “ .. idx .. “: “ .. resolution)
end
SetSelectedAuctionItem
Selectsaniteminanauctionlisting.
SetSelectedAuctionItem(“list“, index)
Chapter 27 API Reference 935
Auction selection is used only for display and internal recordkeeping in the
default UI; it has no direct effect on other Auction APIs.
Arguments:
listType of auction listing (string)
bidderAuctions the player has bid on
listAuctions the player can browse and bid on or buy out
ownerAuctions the player placed
indexIndex of an auction in the listing (number)
SetSelectedBattlefield
Selects a battleground instance in the queueing list.
SetSelectedBattlefield(index)
Selection in the battleground instance list is used only for display in the default
UI and has no effect on other Battlefield APIs.
Arguments:
indexIndex in the battleground queue listing (1for the first avail-
able instance, or between 2 and GetNumBattlefields() for other instances)
(number)
SetSelectedDisplayChannel
Selects a channel in the channel list display.
SetSelectedDisplayChannel(index)
Arguments:
indexIndex of a channel in the channel list display (between 1and
GetNumDisplayChannels())(number)
SetSelectedFaction
Selects a faction in the reputation UI.
SetSelectedFaction(index)
Selection has no bearing on other faction-related APIs; this function merely
facilitates behaviors of Blizzard’s reputation UI.
Arguments:
indexIndex of an entry in the faction list; between 1and GetNumFactions()
(number)
SetSelectedFriend
Selects a character in the player’s friends list.
SetSelectedFriend(index)
Selection in the Friends list is used only for display in the default UI and has no
effect on other Friends list APIs.
Arguments:
indexIndex of a character in the Friends list (between 1and
GetNumFriends())(number)
936 Part IV Reference
SetSelectedIgnore
Selects a character in the player’s ignore list.
SetSelectedIgnore(index)
Selection in the Ignore list is used only for display in the default UI and has no
effect on other Ignore list APIs.
Arguments:
indexIndex of a character in the Ignore list (between 1and GetNum
Ignores())(number)
SetSelectedMute
Selects an entry in the Muted list.
SetSelectedMute(index)
Mute list selection is only used for display purposes in the default UI and has
no effect on other API functions.
Arguments:
indexIndex of an entry in the mute listing (between 1and GetNumMutes())
(number)
SetSelectedSkill
Selects a skill in the Skills UI.
SetSelectedSkill(index)
Selection is only used for display purposes in the default Skills UI and has no
effect on other Skill APIs.
Arguments:
indexIndex of an entry in the skills list (between 1and GetNumSkill
Lines())(number)
SetSendMailCOD
Sets the Cash-On-Delivery cost of the outgoing message.
SetSendMailCOD(amount)
Called in the default UI when clicking its Send button, immediately before
sending the message.
Arguments:
amountCOD cost for the items attached to the message (in copper) (number)
SetSendMailMoney
Sets the amount of money to be sent with the outgoing message.
success = SetSendMailMoney(amount)
Called in the default UI when clicking its Send button, immediately before
sending the message. Causes an error message if the amount plus postage
exceeds the player’s total money.
Arguments:
amountAmount of money to send (in copper) (number)
Chapter 27 API Reference 937
Returns:
success1if the player has enough money to send the message; otherwise nil
(1nil)
Example:
-- Quickly send money to a specified character (only works while at an
-- open mailbox)
function SendCharacterMoney(name, amount)
SetSendMailMoney(amount)
SendMail(name, number/10000 .. “ gold attached“, ““)
end
SetSendMailShowing
Enables or disables shortcuts for attaching items to outgoing mail.
SetSendMailShowing(enable)
When shortcuts are enabled, UseContainerItem() (i.e. right-click in the
default UI’s container frames) attaches the item to the outgoing message
instead of using it.
Arguments:
enableTrue to enable shortcuts; false to disable (boolean)
SetTaxiBenchmarkMode
Enables or disables flight path benchmark mode.
SetTaxiBenchmarkMode(“arg“)
When benchmark mode is enabled, the next taxi flight the player takes will
behave differently: camera movement is disabled and players/creatures/
objects below the flight path will not be shown (allowing for consistent test
conditions). After the flight, framerate statistics will be printed in the chat
window and benchmark mode will be automatically disabled.
Arguments:
argnil, “on“,or1to enable benchmark mode; “off“ or 0 to disable (string)
SetTaxiMap
Sets a Texture object to show the appropriate flight map texture.
SetTaxiMap(texture)
Only has effect while interacting with a flight master (i.e. between the
TAXIMAP_OPENED and TAXIMAP_CLOSED events).
Arguments:
texture—A Texture object (table)
Example:
-- Create a frame, and set it to the taxi map
TestFrame = CreateFrame(“Frame“, “TestFrame“, UIParent)
TestFrame:SetHeight(200)
TestFrame:SetWidth(200)
TestFrame:SetPoint(“CENTER“, UIParent, “CENTER“, 0, 0)
TestFrameTexture = TestFrame:CreateTexture(“TestFrameTexture“, i
938 Part IV Reference
“BACKGROUND“)
TestFrameTexture:SetAllPoints()
SetTaxiMap(TestFrameTexture)
SetTerrainMip
Changes the level of terrain detail displayed.
SetTerrainMip(terrainDetail)
Corresponds to the ‘‘Terrain Blending’’ slider in the default UI’s Video Options
pane.
Arguments:
terrainDetailLevel of terrain detail to be displayed (number)
0—Low detail
1—High detail
SetTracking
Enables a given minimap object/unit tracking ability.
SetTracking(index)
Arguments:
indexIndex of a tracking ability (between 1and GetNumTrackingTypes())
(number)
SetTradeMoney
Offers an amount of money for trade.
SetTradeMoney(amount)
Arguments:
amountAmount of money to offer for trade (in copper) (number)
SetTradeSkillInvSlotFilter
Filters the trade skill listing by equipment slot of items produced.
SetTradeSkillInvSlotFilter(index [, enable [, exclusive]])
Arguments:
indexIndex of an item equipment slot (in the list returned by
GetTradeSkillInvSlots()), or 0for no filter (number)
enable (optional)1to show recipes matching inventory type index in the fil-
tered list; 0 to hide them (number)
exclusive (optional)1to disable other subclass filters when enabling this
one; otherwise nil (1nil)
SetTradeSkillItemLevelFilter
Filters the trade skill listing by required level of items produced.
SetTradeSkillItemLevelFilter(minLevel, maxLevel)
Arguments:
minLevelLowest required level of items to show in the filtered list (number)
maxLevelHighest required level of items to show in the filtered list
(number)
Chapter 27 API Reference 939
SetTradeSkillItemNameFilter
Filters the trade skill listing by name of recipe, item produced, or reagents.
SetTradeSkillItemNameFilter(“text“)
Uses a substring (not exact-match) search: e.g. for a Scribe, the search string
‘‘doc’’ might filter the list to show only Certificate of Ownership because it
matches the word ‘‘documentation’’ in that item’s tooltip; a search for ‘‘stam’’
will match all items providing a Stamina bonus.
Arguments:
textText to search for in recipe names, produced item names or descriptions,
or reagents (string)
SetTradeSkillSubClassFilter
Filters the trade skill listing by subclass of items produced.
SetTradeSkillSubClassFilter(index [, enable [, exclusive]])
Arguments:
indexIndex of an item subclass (in the list returned by GetTradeSkill
SubClasses()), or 0for no filter (number)
enable (optional)1to show recipes matching subclass index in the filtered
list; 0 to hide them (number)
exclusive (optional)1to disable other subclass filters when enabling this
one; otherwise nil (1nil)
SetTrainerServiceTypeFilter
Filters the trainer service listing by service status.
SetTrainerServiceTypeFilter(“type“ [, enable [, exclusive]])
Arguments:
typeA service status (string)
availableServices the player can use
unavailableServices the player cannot currently use
usedServices the player has already used
enable (optional)1to show services matching type in the filtered list; 0 to
hide them (number)
exclusive (optional)1to disable other type filters when enabling this one;
otherwise nil (1nil)
Example:
-- Turn on the “available“ filter
SetTrainerServiceTypeFilter(“available“, 1)
-- Turn on the “used“ filter, and turn off all others
SetTrainerServiceTypeFilter(“used“, 1, 1)
SetTrainerSkillLineFilter
Filters the trainer service listing by skill line.
SetTrainerSkillLineFilter(“type“ [, enable [, exclusive]])
940 Part IV Reference
The default UI does not provide control for skill line filters, but they can
nonetheless be used to alter the contents of the trainer service listing.
Arguments:
typeIndex of a skill line filter (in the list returned by GetTrainerSkill
Lines())(string)
enable (optional)1to show services matching the given skill line in the fil-
tered list; 0 to hide them (number)
exclusive (optional)1to disable other skill line filters when enabling this
one; otherwise nil (1nil)
SetUIVisibility
Enables or disables display of UI elements in the 3-D world.
SetUIVisibility(visible)
Applies only to 2-D UI elements displayed in the 3-D world: nameplates and
raid target icons (skull, circle, square, etc). Does not directly control nameplates
and target icons; only affects whether they are displayed (see the
nameplateShowEnemies/nameplateShowFriends CVars and
SetRaidTarget functions for direct control).
Does not apply to 3-D UI elements such as the selection circle, area-effect
targeting indicator, vehicle weapon aim indicator, etc.
Arguments:
visibleTrue to enable display of UI elements in the 3-D world; false to dis-
able (boolean)
SetView
Moves the camera to a saved camera setting.
SetView(index)
There are five ‘‘slots’’ for saved camera settings, indexed 1-5. These views can
be set and accessed directly using SaveView() and SetView(), and cycled
through using NextView() and PrevView().
Arguments:
indexIndex of a saved camera setting (between 1and 5) (number)
SetWatchedFactionIndex
Makes a faction the ‘‘watched’’ faction (displayed on the XP bar in the default
UI).
SetWatchedFactionIndex(index)
Arguments:
indexIndex of an entry in the faction list; between 1and GetNumFactions()
(number)
SetWhoToUI
Changes the delivery method for results from SendWho() queries.
SetWhoToUI(state)
Chapter 27 API Reference 941
In the default UI, results delivered in CHAT_MSG_SYSTEM are printed in the
main chat window; results delivered in a WHO_LIST_UPDATE event cause the
FriendsFrame to be shown, displaying the results in its ‘‘Who’’ tab.
Arguments:
stateNumber identifying a delivery method (number)
0Send results of three entries or fewer in CHAT_MSG_SYSTEM events
and results of greater than three entries in a WHO_LIST_UPDATE event
1Send all results in a WHO_LIST_UPDATE event
SetupFullscreenScale
Sizes a frame to take up the entire screen regardless of screen resolution.
SetupFullscreenScale(frame)
Arguments:
frameFrame to resize to full screen (table)
ShowBattlefieldList
Requests to change instances for a battleground to which the player is already
queued.
ShowBattlefieldList(index)
Causes the BATTLEFIELDS_SHOW event to fire, allowing the player to review
the battleground’s list of available instances and queue for a different one if
desired.
Arguments:
indexIndex of a battleground/arena queue the player has joined (between 1
and MAX_BATTLEFIELD_QUEUES)(number)
ShowBuybackSellCursor
Changes the cursor to prepare for repurchasing an item recently sold to a
vendor.
ShowBuybackSellCursor(index)
Only changes the cursor image and mode if the given index contains an item.
Arguments:
indexIndex of an item in the buyback listing (between 1and
GetNumBuybackItems())(number)
ShowCloak
Enables or disables display of the player’s cloak.
ShowCloak(show)
Only affects the player’s appearance; does not change the other effects of
having the cloak equipped. Determines not only the appearance of the player
character on the local client, but the way other players see the character as well.
Arguments:
show1to display the player’s cloak; nil to hide it (1nil)
942 Part IV Reference
ShowContainerSellCursor
Changes the cursor to prepare for selling an item in the player’s bags to a
vendor.
ShowContainerSellCursor(container, slot)
Only changes the cursor image and mode if the given container and slot
contain an item.
While the cursor is in ‘‘sell’’ mode, UseContainerItem() sells the item to the
vendor instead of using it.
Arguments:
containerIndex of one of the player’s bags or other containers (number,con-
tainerID)
slotIndex of an item slot within the container (number, containerSlotID)
ShowFriends
Requests friends/ignore list information from the server.
Information is not returned immediately; the FRIENDLIST_UPDATE event fires
when data becomes available for use by Friends/Ignore API functions.
ShowHelm
Enables or disables display of the player’s headgear.
ShowHelm(show)
Only affects the player’s appearance; does not change the other effects of
having the headgear equipped. Determines not only the appearance of the
player character on the local client, but the way other players see the character
as well.
Arguments:
show1to display the player’s headgear; nil to hide it (1nil)
ShowInventorySellCursor
Changes the cursor to prepare for selling an equipped item to a vendor.
ShowInventorySellCursor(slot)
Only changes the cursor image and mode if the given slot contains an item.
(Unlike ShowContainerSellCursor(), does not change the behavior of other
functions to enable selling of items. Unused in the default UI.)
Arguments:
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
ShowMerchantSellCursor
Changes the cursor to prepare for buying an item from a vendor.
ShowMerchantSellCursor(index)
Only changes the cursor image and mode if the given index contains an item.
Arguments:
indexIndex of an item in the vendor’s listing (between 1and GetMerchant
NumItems())(number)
Chapter 27 API Reference 943
ShowMiniWorldMapArrowFrame
Shows or hides the battlefield minimap’s player arrow.
ShowMiniWorldMapArrowFrame(show)
Arguments:
showIf the battlefield minimap’s player arrow should be shown (boolean)
ShowRepairCursor
Puts the cursor in item repair mode.
Unlike most other cursor functions, this functions changes the behavior as well
as the appearance of the mouse cursor: while repair mode is active, calling
PickupContainerItem() or PickupInventoryItem() will attempt to repair
the item (and deduct the cost of such from the player’s savings) instead of
putting it on the cursor.
Only has effect while the player is interacting with a vendor which can
perform repairs; i.e. between the MERCHANT_SHOW and MERCHANT_CLOSED
events, and only if CanMerchantRepair() returns 1.
ShowingCloak
Returns whether the player’s cloak is displayed.
isShown = ShowingCloak()
Determines not only the appearance of the player character on the local client,
but the way other players see the character as well.
Returns:
isShown1if the player’s cloak is shown; otherwise nil (1nil)
ShowingHelm
Returns whether the player’s headgear is displayed.
isShown = ShowingHelm()
Determines not only the appearance of the player character on the local client,
but the way other players see the character as well.
Returns:
isShown1if the player’s headgear is shown; otherwise nil (1nil)
SignPetition
Signs the currently offered petition.
Protected SitStandOrDescendStart
Causes the player character to sit down if standing and vice versa (or begins
descent if swimming or flying).
Used by the SITORSTAND binding, which also controls descent when
swimming or flying.
SocketContainerItem
Opens an item from the player’s bags for socketing.
SocketContainerItem(container, slot)
944 Part IV Reference
Arguments:
containerIndex of one of the player’s bags or other containers (number,con-
tainerID)
slotIndex of an item slot within the container (number, containerSlotID)
SocketInventoryItem
Opens an equipped item for socketing.
SocketInventoryItem(slot)
Arguments:
slotAn inventory slot number, as can be obtained from GetInventorySlot
Info (number,inventoryID)
SortArenaTeamRoster
Sorts the selected arena team’s roster.
SortArenaTeamRoster(“sortType“)
Affects the ordering of member information returned by
GetArenaTeamRosterInfo. Sorting by the same criterion repeatedly reverses
the sort order.
Arguments:
sortTypeCriterion for sorting the roster (string)
classSort by class
name—Sort by name
playedSort by number of games played in the current week
ratingSort by personal rating
seasonplayedSort by number of games played in the current arena season
seasonwonSort by number of games won in the current arena season
wonSort by number of games won in the current week
SortAuctionApplySort
Applies a set of auction listing sort criteria set via SortAuctionSetSort.
SortAuctionApplySort(“list“)
Sort criteria are applied server-side, affecting not only the order of items within
one ‘‘page’’ of listings but the order in which items are collected into pages.
Any currently displayed listings are re-sorted server-side: the
AUCTION_ITEM_LIST_UPDATE,AUCTION_BIDDER_LIST_UPDATE,or
AUCTION_OWNED_LIST_UPDATE event fires once the re-sorted data is available
to the client; listing information can then be retrieved using
GetAuctionItemInfo() or other Auction APIs.
Arguments:
listType of auction listing (string)
bidderAuctions the player has bid on
listAuctions the player can browse and bid on or buy out
ownerAuctions the player placed
Chapter 27 API Reference 945
SortAuctionClearSort
Clears any current sorting rules for an auction house listing.
SortAuctionClearSort(“list“)
Arguments:
listType of auction listing (string)
bidderAuctions the player has bid on
listAuctions the player can browse and bid on or buy out
ownerAuctions the player placed
SortAuctionSetSort
Builds a list of sort criteria for auction listings.
SortAuctionSetSort(“list“, “sort“, reversed)
Has no effect until SortAuctionApplySort(type) is called; thus, this
function can be called repeatedly to build a complex set of sort criteria. Sort
criteria are applied server-side, affecting not only the order of items within one
‘‘page’’ of listings but the order in which items are collected into pages.
Criteria are applied in the order set by this function; i.e. the last criterion set
becomes the primary sort criterion (see example).
Arguments:
listType of auction listing (string)
bidderAuctions the player has bid on
listAuctions the player can browse and bid on or buy out
ownerAuctions the player placed
sortCriterion to add to the sort (string)
bidAmount of the current or minimum bid on the item
buyoutBuyout price of the item
durationTime remaining before the auction expires
levelRequired character level to use or equip the item
minbidbuyoutBuyout price, or minimum bid if no buyout price is
available
name—Name of the item
qualityitemQuality of the item
quantityNumber of stacked items in the auction
sellerName of the character who created the auction (or in the owner list-
ing, the current high bidder)
statusStatus of the auction (e.g. in the bidder listing, whether the player
has been outbid)
reversedTrue to sort in reverse order; otherwise false. ‘‘Reverse’’
here is relative to the default order, not to absolute value: e.g. the
default order for quality is descending (Epic, Rare, Uncommon, etc),
but the default order for level is ascending (1-80) (boolean)
946 Part IV Reference
Example:
-- clear any existing criteria
SortAuctionClearSort(“list“)
-- then, apply some criteria of our own
SortAuctionSetSort(“list“, “name“)
SortAuctionSetSort(“list“, “level“, 1)
SortAuctionSetSort(“list“, “quality“)
-- apply the criteria to the server query
SortAuctionApplySort(“list“)
-- results are now sorted by quality, level and name:
-- higher quality items are listed before lower (e.g. Epic,
-- Rare, Uncommon)
-- items with the same quality are sorted descending by level
-- (e.g. 80, 75, 30, 1)
-- items with the same quality and level are sorted alphabetically
-- by name
SortBattlefieldScoreData
Sorts the battleground scoreboard.
SortBattlefieldScoreData(“sortType“)
Battleground-specific statistics include flags captured in Warsong Gulch,
towers assaulted in Alterac Valley, etc. For the name and icon associated with
each statistic, see GetBattlefieldStatInfo().
Arguments:
sortTypeCriterion for sorting the scoreboard data (string)
classSort by character class
cpSorts by honor points gained
damageSorts by damage done
deaths—Sort by number of deaths
healingSorts by healing done
hkSorts by number of honor kills
killsSort by number of kills
nameSort by participant name
stat1Battlefield-specific statistic 1
stat2Battlefield-specific statistic 2
stat3Battlefield-specific statistic 3
stat4Battlefield-specific statistic 4
stat5Battlefield-specific statistic 5
stat6Battlefield-specific statistic 6
stat7Battlefield-specific statistic 7
team—Sortbyteamname
Chapter 27 API Reference 947
SortGuildRoster
Sorts the guild roster.
SortGuildRoster(“type“)
Sortingrepeatedlybythesamecriterionwill reverse the sort order. Previous
sorts are reused when a new criterion is applied: to sort by two criteria, sort
first by the secondary criterion and then by the primary criterion.
Arguments:
typeCriterion by which to sort the roster (string)
classSort by class name
levelSort by character level
name—Sort by name
noteSort by guild note
onlineSory by last online time
rankSort by guild rank
zoneSort by current zone name
SortLFG
Sets the sort order for Looking for More results.
SortLFG(“sortType“)
Arguments:
sortTypeCriterion for sorting the LFM results list (string)
classSort by player class
levelSort by player level
name—Sort by player name
numPartyMembersSort by number of party members
zoneSort by current zone
SortWho
Sorts the Who system query results list.
SortWho(“sortType“)
Sorting by the same criterion twice will reverse the sort order.
Arguments:
sortTypeCriterion for sorting the list (string)
classSort by class name
guildSort by guild name
levelSort by player level
name—Sort by player name
raceSort by race name
zoneSort by current zone name
Sound_ChatSystem_GetInputDriverNameByIndex
Returns the name of the given chat system sound input driver.
Sound_ChatSystem_GetInputDriverNameByIndex(index)
948 Part IV Reference
Arguments:
indexThe desired index (number)
Sound_ChatSystem_GetNumInputDrivers
Returns the number of chat system sound input drivers.
Sound_ChatSystem_GetNumOutputDrivers
Returns the number of chat system sound output drivers.
Sound_ChatSystem_GetOutputDriverNameByIndex
Returns the name of the given chat system sound output driver.
Sound_ChatSystem_GetOutputDriverNameByIndex(index)
Arguments:
indexThe desired index (number)
Sound_GameSystem_GetInputDriverNameByIndex
Returns the name of the given game sound input driver.
Sound_GameSystem_GetInputDriverNameByIndex(index)
Arguments:
indexThe desired index (number)
Sound_GameSystem_GetNumInputDrivers
Returns the number of game sound input drivers.
Sound_GameSystem_GetNumOutputDrivers
Returns the number of game sound output drivers.
Sound_GameSystem_GetOutputDriverNameByIndex
Returns the name of the given game sound output driver.
Sound_GameSystem_GetOutputDriverNameByIndex(index)
Arguments:
indexThe desired index (number)
Sound_GameSystem_RestartSoundSystem
Restarts the game’s sound systems.
SpellCanTargetGlyph
Returns whether the spell currently awaiting a target requires a glyph slot to
be chosen.
canTarget = SpellCanTargetGlyph()
Only applies when the player has attempted to cast a spellin this case, the
‘‘spell’’ cast when one uses a glyph itembut the spell requires a target before
it can begin casting (i.e. the glowing hand cursor is showing).
Returns:
canTarget1if the spell can target glyph slots (1nil)
SpellCanTargetItem
Returns whether the spell currently awaiting a target requires an item to be
chosen.
canTarget = SpellCanTargetItem()
Chapter 27 API Reference 949
Only applies when the player has attempted to cast a spell but the spell
requires a target before it can begin casting (i.e. the glowing hand cursor is
showing).
Returns:
canTarget1if the spell can target an item; otherwise nil (1nil)
SpellCanTargetUnit
Returns whether the spell currently awaiting a target can target a given unit.
canTarget = SpellCanTargetUnit(“unit“) or SpellCanTargetUnit(“name“)
Only applies when the player has attempted to cast a spell but the spell
requires a target before it can begin casting (i.e. the glowing hand cursor is
showing).
Arguments:
unitA unit to target (string,unitID)
nameThe name of a unit to target; only valid for player,pet, and party/raid
members (string)
Returns:
canTarget1if the spell currently awaiting targeting can target the given unit
(1nil)
SpellHasRange
Returns whether an item has a range limitation for its use.
hasRange = SpellHasRange(index, “bookType“) or SpellHasRange(“name“)
For example: Shadowbolt can only be used on a unit within a given range of
the player; Ritual of Summoning requires a target but has no range restriction;
Fel Armor has no target and thus no range restriction.
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
Returns:
hasRange1if the spell has an effective range; otherwise nil.(1nil)
SpellIsTargeting
Returns whether a spell is currently awaiting a target.
isTargeting = SpellIsTargeting()
Returns:
isTargeting1if a spell is currently awaiting a target; otherwise nil (1nil)
Protected SpellStopCasting
Stops casting or targeting the spell in progress.
950 Part IV Reference
Protected SpellStopTargeting
Cancels the spell currently awaiting a target.
When auto-self cast is not enabled and the player casts a spell that requires a
target, the cursor changes to a glowing hand so the user can select a target. This
function cancels targeting mode so the player can cast another spell.
Protected SpellTargetItem
Casts the spell currently awaiting a target on an item.
SpellTargetItem(itemID) or SpellTargetItem(“itemName“) or i
SpellTargetItem(“itemLink“)
Usable when the player has attempted to cast a spell (e.g. an Enchanting recipe
or the ‘‘Use:’’ effect of a sharpening stone or fishing lure) but the spell requires
a target before it can begin casting (i.e. the glowing hand cursor is showing).
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Protected SpellTargetUnit
Casts the spell currently awaiting a target on a unit.
SpellTargetUnit(“unit“) or SpellTargetUnit(“name“)
Arguments:
unitA unit to target (string,unitID)
nameThe name of a unit to target; only valid for player,pet, and party/raid
members (string)
SplitContainerItem
Picks up only part of a stack of items from one of the player’s bags or other
containers.
SplitContainerItem(container, slot, amount)
Has no effect if the given amount is greater than the number of items stacked in
the slot.
Arguments:
containerIndex of one of the player’s bags or other containers (number,con-
tainerID)
slotIndex of an item slot within the container (number, containerSlotID)
amountNumber of items from the stack to pick up (number)
SplitGuildBankItem
Picks up only part of a stack of items from the guild bank.
SplitGuildBankItem(tab, slot, amount)
Has no effect if the given amount is greater than the number of items stacked in
the slot.
Chapter 27 API Reference 951
Arguments:
tabIndex of a guild bank tab (number)
slotIndex of an item slot in the guild bank tab (number)
amountNumber of items from the stack to pick up (number)
StablePet
Puts the player’s current pet into the stables.
Protected StartAttack
Begins auto-attack against a specified target.
StartAttack(“unit“) or StartAttack(“name“)
Arguments:
unitA unit to attack (string,unitID)
nameThe name of a unit to attack (string)
StartAuction
Creates an auction for the item currently in the ‘‘auction item’’ slot.
StartAuction(minBid, buyoutPrice, runTime)
Has no effect unless an item has been placed in the Create Auction UI’s
‘‘auction item’’ slot (see ClickAuctionSellItemButton()).
Arguments:
minBidMinimum bid for the auction (in copper) (number)
buyoutPriceBuyout price for the auction (in copper) (number)
runTimeRun time until the auction expires (in minutes, but only values listed
below are allowed) (number)
720—12 hours
1440—24 hours
2880—48 hours
StartDuel
Challenges another player to a duel.
StartDuel(“unit“) or StartDuel(“name“ [, exactMatch])
Arguments:
unitA unit to target (string,unitID)
nameName of a unit to target (string)
exactMatch (optional)True to check only units whose name exactly
matches the name given; false to allow partial matches (boolean)
Protected StopAttack
Stops auto-attack if active.
StopCinematic
Exits a currently playing in-game cinematic.
Applies to in-game-engine cinematics (such as when logging into a new
character for the first time), not prerecorded movies.
952 Part IV Reference
Protected StopMacro
Stops execution of a running macro.
StopMusic
Stops currently playing in-game music.
StopTradeSkillRepeat
Cancels repetition of a trade skill recipe.
If a recipe is currently being performed, it will continue, but further scheduled
repetitions will be canceled.
Protected StrafeLeftStart
Begins moving the player character sideways to his or her left.
Protected StrafeLeftStop
Ends movement initiated by StrafeLeftStart.
Protected StrafeRightStart
Begins moving the player character sideways to his or her right.
Protected StrafeRightStop
Ends movement initiated by StrafeRightStart.
Protected Stuck
Uses the auto-unstuck feature.
SummonFriend
Summons a unit whose account is linked to the player’s via the
Recruit-a-Friend program.
SummonFriend(“name“) or SummonFriend(“unit“)
Does not instantly teleport the unit. Calling this function begins casting the
Summon Friend ‘‘spell’’, and once it completes the unit is prompted to accept
or decline the summons.
Arguments:
nameExact name of a player to summon (only applies to units in the player’s
party or raid) (string)
unitA unit to summon (string,unitID)
SwapRaidSubgroup
Swaps two raid members between subgroups in the raid.
SwapRaidSubgroup(index1, index2)
Only has effect if the player is the raid leader or a raid assistant. To move a
member into a non-full subgroup without switching places with another
member, see SetRaidSubgroup().
Arguments:
index1Index of the first raid member (between 1and GetNumRaid
Members()); matches the numeric part of the unit’s raid unitID,e.g.21 for
raid21 (number)
index2Index of the other raid member (number)
Chapter 27 API Reference 953
Confirmation TakeInboxItem
Retrieves an item attachment from a message in the player’s inbox (accepting
COD charges if applicable).
TakeInboxItem(mailID, attachmentIndex)
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
attachmentIndexIndex of an attachment to the message (between
1and select(8,GetInboxHeaderInfo(mailID)))(number)
TakeInboxMoney
Retrieves any money attached to a message in the player’s inbox.
TakeInboxMoney(mailID)
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
TakeInboxTextItem
Requests a copy of a message’s body text as an item.
TakeInboxTextItem(mailID)
The text of an in-game mail can be retrieved as a readable ‘‘Plain Letter’’ item
to store in the player’s bags; this function sends a request to the server for this
item, causing the standard inventory events to fire as the item is placed into the
player’s inventory.
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
TakeTaxiNode
Embarks on a taxi flight to a given destination.
TakeTaxiNode(index)
Only has effect while interacting with a flight master (i.e. between the
TAXIMAP_OPENED and TAXIMAP_CLOSED events).
Arguments:
indexIndex of a flight point (between 1and NumTaxiNodes())(number)
Protected TargetLastEnemy
Targets the most recently targeted enemy unit.
Protected TargetLastFriend
Targets the most recently targeted friendly unit.
Protected TargetLastTarget
Targets the most recently targeted unit.
954 Part IV Reference
Protected TargetNearest
Cycles targets through nearest units regardless of reaction/affiliation.
TargetNearest([backward])
Arguments:
backward (optional)Reverses direction of target cycling if true
(as with the default TAB vs. SHIFT-TAB bindings) (boolean)
Protected TargetNearestEnemy
Cycles your target through the nearest enemy units.
TargetNearestEnemy(backward)
This function can only be called once per hardware event.
Arguments:
backwardReverses the direction of the cycling if true (e.g. TAB vs.
SHIFT-TAB) (boolean)
Protected TargetNearestEnemyPlayer
Cycles targets through nearby enemy player units.
TargetNearestEnemyPlayer(backward)
Arguments:
backwardReverses direction of target cycling if true (as with the default TAB
vs. SHIFT-TAB bindings) (boolean)
Protected TargetNearestFriend
Cycles targets through nearby friendly units.
TargetNearestFriend(backward)
Arguments:
backwardReverses direction of target cycling if true (as with the default TAB
vs. SHIFT-TAB bindings) (boolean)
Protected TargetNearestFriendPlayer
Cycles targets through nearby friendly player units.
TargetNearestFriendPlayer(backward)
Arguments:
backwardReverses direction of target cycling if true (as with the default TAB
vs. SHIFT-TAB bindings) (boolean)
Protected TargetNearestPartyMember
Cycles targets through nearby party members.
TargetNearestPartyMember(backward)
Arguments:
backwardReverses direction of target cycling if true (as with the default TAB
vs. SHIFT-TAB bindings) (boolean)
Chapter 27 API Reference 955
Protected TargetNearestRaidMember
Cycles targets through nearby raid members.
TargetNearestRaidMember(backward)
Arguments:
backwardReverses direction of target cycling if true (as with the default TAB
vs. SHIFT-TAB bindings) (boolean)
Protected TargetTotem
Targets one of the player’s totems (or a Death Knight’s ghoul).
TargetTotem(slot)
Totem functions are also used for ghouls summoned by a Death Knight’s Raise
Dead ability (if the ghoul is not made a controllable pet by the Master of
Ghouls talent).
Arguments:
slotWhich totem to target (number)
1Fire (or Death Knight’s ghoul)
2—Earth
3—Water
4—Air
Protected TargetUnit
Targets a unit.
TargetUnit(“unit“) or TargetUnit(“name“ [, exactMatch])
Passing nil is equivalent to calling ClearTarget()).
Arguments:
unitA unit to target (string,unitID)
nameName of a unit to target (string)
exactMatch (optional)True to check only units whose name exactly
matches the name given; false to allow partial matches (boolean)
TaxiGetDestX
Returns the horizontal coordinate of a taxi flight’s destination node.
dX = TaxiGetDestX(source, dest)
Used in the default UI to draw lines between nodes; TaxiNodeSetCurrent()
should be called first so the client can compute routes.
Only returns valid data while interacting with a flight master (i.e. between the
TAXIMAP_OPENED and TAXIMAP_CLOSED events).
Arguments:
sourceIndex of the source flight point (between 1and NumTaxiNodes())
(number)
destIndex of the destination flight point (between 1and NumTaxiNodes())
(number)
956 Part IV Reference
Returns:
dXX coordinate of the destination taxi node (as a proportion of
the taxi map’s width; 0 =left edge, 1=right edge) (number)
TaxiGetDestY
Returns the vertical coordinate of a taxi flight’s destination node.
dY = TaxiGetDestY(source, dest)
Used in the default UI to draw lines between nodes; TaxiNodeSetCurrent()
should be called first so the client can compute routes.
Only returns valid data while interacting with a flight master (i.e. between the
TAXIMAP_OPENED and TAXIMAP_CLOSED events).
Arguments:
sourceIndex of the source flight point (between 1and NumTaxiNodes())
(number)
destIndex of the destination flight point (between 1and NumTaxiNodes())
(number)
Returns:
dYY coordinate of the destination taxi node (as a proportion of the taxi map’s
height; 0 =bottom, 1=top) (number)
TaxiGetSrcX
Returns the horizontal coordinate of a taxi flight’s source node.
sX = TaxiGetSrcX(source, dest)
Used in the default UI to draw lines between nodes; TaxiNodeSetCurrent()
should be called first so the client can compute routes.
Only returns valid data while interacting with a flight master (i.e. between the
TAXIMAP_OPENED and TAXIMAP_CLOSED events).
Arguments:
sourceIndex of the source flight point (between 1and NumTaxiNodes())
(number)
destIndex of the destination flight point (between 1and NumTaxiNodes())
(number)
Returns:
sXX coordinate of the source taxi node (as a proportion of the taxi map’s
width; 0 =left edge, 1=right edge) (number)
TaxiGetSrcY
Returns the vertical coordinate of a taxi flight’s source node.
sY = TaxiGetSrcY(source, dest)
Used in the default UI to draw lines between nodes; TaxiNodeSetCurrent()
should be called first so the client can compute routes.
Only returns valid data while interacting with a flight master (i.e. between the
TAXIMAP_OPENED and TAXIMAP_CLOSED events).
Chapter 27 API Reference 957
Arguments:
sourceIndex of the source flight point (between 1and NumTaxiNodes())
(number)
destIndex of the destination flight point (between 1and NumTaxiNodes())
(number)
Returns:
sYY coordinate of the source taxi node (as a proportion of the taxi map’s
height; 0 =bottom, 1=top) (number)
TaxiNodeCost
Returns the cost to fly to a given taxi node.
cost = TaxiNodeCost(index)
Only returns valid data while interacting with a flight master (i.e. between the
TAXIMAP_OPENED and TAXIMAP_CLOSED events).
Arguments:
indexIndex of a flight point (between 1and NumTaxiNodes())(number)
Returns:
costPrice of a flight to the given node (in copper) (number)
TaxiNodeGetType
Returns the type of a flight point.
type = TaxiNodeGetType(index)
Only returns valid data while interacting with a flight master (i.e. between the
TAXIMAP_OPENED and TAXIMAP_CLOSED events).
Arguments:
indexIndex of a flight point (between 1and NumTaxiNodes())(number)
Returns:
typeType of the flight point (string)
CURRENTThe player’s current location
DISTANTUnreachable from the current location
NONENot currently in use
REACHABLEReachable from the current location (directly or through other
nodes)
TaxiNodeName
Returns the name of a flight point.
name = TaxiNodeName(index)
Only returns valid data while interacting with a flight master (i.e. between the
TAXIMAP_OPENED and TAXIMAP_CLOSED events).
Arguments:
indexIndex of a flight point (between 1and NumTaxiNodes())(number)
958 Part IV Reference
Returns:
nameName of the taxi node (string)
TaxiNodePosition
Returns the position of a flight point on the taxi map.
x, y = TaxiNodePosition(index)
Only returns valid data while interacting with a flight master (i.e. between the
TAXIMAP_OPENED and TAXIMAP_CLOSED events).
Arguments:
indexIndex of a flight point (between 1and NumTaxiNodes())(number)
Returns:
xHorizontal coordinate of the taxi node (as a proportion of the taxi map’s
width; 0 =left edge, 1=right edge) (number)
yVertical coordinate of the taxi node (as a proportion of the taxi map’s height;
0=bottom, 1=top) (number)
TaxiNodeSetCurrent
Sets the ‘‘current’’ flight path node.
TaxiNodeSetCurrent(slot)
Used in the default UI when mousing over a node; tells the client to compute
the route paths involving the node (see TaxiGetSrcX() et al).
Arguments:
slotThe internal index of a flight path node (number)
Protected ToggleAutoRun
Starts or stops the player character automatically moving forward.
TogglePVP
Switches the player’s desired PvP status.
If PvP is currently disabled for the player, it becomes enabled immediately. If
PvP is enabled, it will become disabled after five minutes of no PvP activity.
Protected TogglePetAutocast
Turns autocast on or off for a pet action.
TogglePetAutocast(index)
Turns autocast on if not autocasting and vice versa.
Arguments:
indexIndex of a pet action button (between 1and NUM_PET_ACTION_SLOTS)
(number)
Protected ToggleRun
Switches the character’s ground movement mode between running and
walking.
If running, switches to walking, and vice versa. Has no effect on swimming or
flying speed.
Chapter 27 API Reference 959
ToggleSheath
Sheaths or unsheaths the player character’s hand-held items.
Calling repeatedly will cause the player character to draw his or her melee
weapons, followed by his or her range weapon, followed by hiding all
weapons.
ToggleSpellAutocast
Enables or disables automatic casting of a spell.
ToggleSpellAutocast(index, “bookType“) or ToggleSpellAutocast(“name“)
Generally only pet spells can be autocast.
Arguments:
indexIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
petThe pet’s spellbook
spellThe player’s spellbook
nameName of a spell (string)
TradeSkillOnlyShowMakeable
Filters the trade skill listing by whether the player currently has enough
reagents for each recipe.
TradeSkillOnlyShowMakeable(filter)
Arguments:
filterTrue to filter the recipe listing to show only recipes for which the
player currently has enough reagents; false to show all recipes (boolean)
TradeSkillOnlyShowSkillUps
Filters the trade skill listing by whether the player can gain skill ranks from
each recipe.
TradeSkillOnlyShowSkillUps(filter)
The default UI does not provide controls for this filter, but it can nonetheless be
used to alter the contents of the trade skill recipe listing.
Arguments:
filterTrue to filter the recipe listing to show only recipes which the player
can gain skill ranks by performing; false to show all recipes (boolean)
TurnInArenaPetition
Turns in a petition creating an arena team.
TurnInArenaPetition(teamSize, bg_red, bg_green, bg_blue, emblem, i
emblem_red, emblem_green, emblem_blue, border, border_red, i
border_green, border_blue)
Arguments:
teamSizeSize of arena team to create (number)
2—2v2
3—3v3
5—5v5
960 Part IV Reference
bg_redRed component of the color value for the team banner’s background
(number)
bg_greenGreen component of the color value for the team banner’s back-
ground (number)
bg_blueBlue component of the color value for the team banner’s background
(number)
emblemIndex of the team’s emblem graphic; full path to the emblem texture
can be found using the format “Interface\PVPFrame\Icons\PVP-Banner-
Emblem-“..emblem (number)
emblem_redRed component of the color value for the team banner’s emblem
(number)
emblem_greenGreen component of the color value for the team banner’s
emblem (number)
emblem_blueBlue component of the color value for the team banner’s
emblem (number)
borderIndex of the team’s border graphic; full path to the border texture
can be found by using the format “Interface\PVPFrame\PVP-Banner-“..
teamSize..“-Border-“..border (number)
border_redRed component of the color value for the team banner’s border
(number)
border_greenGreen component of the color value for the team banner’s bor-
der (number)
border_blueBlue component of the color value for the team banner’s border
(number)
TurnInGuildCharter
Turns in a completed guild charter.
Usable if the player is interacting with a guild registrar (i.e. between the
GUILD_REGISTRAR_SHOW and GUILD_REGISTRAR_CLOSED events).
Protected TurnLeftStart
Begins turning the player character to the left.
‘‘Left’’ here is relative to the player’s facing; i.e. if looking down at the
character from above, he or she turns counter-clockwise.
Used by the TURNLEFT binding.
Protected TurnLeftStop
Ends movement initiated by TurnLeftStart.
Protected TurnOrActionStart
Begins character steering or interaction (equivalent to right-clicking in the 3-D
world).
After calling this function (i.e. while the right mouse button is held), cursor
movement rotates (or steers) the player character, altering yaw (facing) and/or
pitch (vertical movement angle) as well as camera position. Final results vary
by context and are determined when calling TurnOrActionStop()
(i.e. releasing the right mouse button).
Chapter 27 API Reference 961
Used by the TURNORACTION binding (not customizable in the default UI),
which is bound to the right mouse button by default.
Protected TurnOrActionStop
Ends action initiated by TurnOrActionStart.
After calling this function (i.e. releasing the right mouse button), character
steering stops and normal cursor movement resumes. If the cursor has not
moved significantly since calling TurnOrActionStart() (i.e. pressing the
right mouse button), results vary by context:
if the cursor is over a nearby unit, interacts with (or attacks) that unit, mak-
ing it the player’s target.
if the cursor is over a nearby interactable world object (e.g. mailbox,
treasure chest, or quest object), interacts with (or uses) that object.
if the cursor is over a faraway unit or world object and the ‘‘Click-to-Move’’
option is enabled (i.e. the ‘‘autointeract’’ CVar is ‘‘1’’), attempts
to move the player character to the unit/object and interact with it once
nearby.
if the cursor is over a faraway world object and the ‘‘Click-to-Move’’
option is disabled, fires a UI_ERROR_MESSAGE event indicat-
ing the player is too far away to interact with the object.
otherwise, does nothing.
Used by the TURNORACTION binding (not customizable in the default UI),
which is bound to the right mouse button by default.
Protected TurnRightStart
Begins turning the player character to the right.
‘‘Right’’ here is relative to the player’s facing; i.e. if looking down at the
character from above, he or she turns clockwise.
Used by the TURNRIGHT binding.
Protected TurnRightStop
Ends movement initiated by TurnRightStart.
TutorialsEnabled
Returns whether contextual tutorials are enabled.
enabled = TutorialsEnabled()
Returns:
enabled1if contextual tutorials are enabled; otherwise nil (1nil)
UninviteUnit
Removes a character from the player’s party or raid.
UninviteUnit(“name“)
Only works if the player is the party leader, raid leader, or raid assistant.
Arguments:
nameName of a character to uninvite (string)
962 Part IV Reference
UnitAffectingCombat
Returns whether a unit is currently in combat.
inCombat = UnitAffectingCombat(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
inCombat1if the unit is currently involved in combat; otherwise nil (1nil)
UnitArmor
Returns the player’s or pet’s armor value.
base, effectiveArmor, armor, posBuff, negBuff = UnitArmor(“unit“)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
Returns:
baseThe unit’s base armor value (number)
effectiveArmorThe unit’s effective armor value (number)
armorThe unit’s current armor value (number)
posBuffPositive modifiers to armor value (number)
negBuffNegative modifiers to armor value (number)
UnitAttackBothHands
Returns information about the player’s or pet’s weapon skill.
mainHandAttackBase, mainHandAttackMod, offHandHandAttackBase, i
offHandAttackMod = UnitAttackBothHands(“unit“)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
Returns:
mainHandAttackBaseThe unit’s base weapon skill for the main hand
weapon (number)
mainHandAttackModTemporary modifiers to main hand weapon skill
(number)
offHandHandAttackBaseThe unit’s base weapon skill for the off hand
weapon (number)
offHandAttackModTemporary modifiers to off hand weapon skill (number)
UnitAttackPower
Returns the player’s or pet’s melee attack power.
base, posBuff, negBuff = UnitAttackPower(“unit“)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
Returns:
baseThe unit’s base attack power (number)
posBuffTotal effect of positive buffs to attack power (number)
negBuffTotal effect of negative buffs to attack power (number)
Chapter 27 API Reference 963
UnitAttackSpeed
Returns information about the player’s or pet’s melee attack speed.
speed, offhandSpeed = UnitAttackSpeed(“unit“)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
Returns:
speedCurrent speed of the unit’s main hand attack (number of seconds per
attack) (number)
offhandSpeedCurrent speed of the unit’s off hand attack (number of seconds
per attack) (number)
UnitAura
Returns information about buffs/debuffs on a unit.
name, rank, icon, count, dispelType, duration, expires, caster, i
isStealable = UnitAura(“unit“, index [, “filter“]) or i
UnitAura(“unit“, “name“ [, “rank“ [, “filter“]])
Arguments:
unit—A unit to query (string,unitID)
indexIndex of an aura to query (number)
nameName of an aura to query (string)
rank (optional)Secondary text of an aura to query (often a rank; e.g. ‘‘Rank 7’’)
(string)
filter (optional)A list of filters to use separated by the pipe ‘|’character;
e.g. “RAID|PLAYER“ will query group buffs cast by the player (string)
CANCELABLEShow auras that can be cancelled
HARMFULShow debuffs only
HELPFULShow buffs only
NOT_CANCELABLEShow auras that cannot be cancelled
PLAYERShow auras the player has cast
RAIDWhen used with a HELPFUL filter it will show auras the
player can cast on party/raid members (as opposed to self buffs).
If used with a HARMFUL filter it will return debuffs the player can cure
Returns:
nameName of the aura (string)
rankSecondary text for the aura (often a rank; e.g. ‘‘Rank 7’’) (string)
iconPath to an icon texture for the aura (string)
countThe number of times the aura has been applied (number)
dispelTypeType of aura (relevant for dispelling and certain other
mechanics); nil if not one of the following values: (string)
Curse
Disease
Magic
Poison
964 Part IV Reference
durationTotal duration of the aura (in seconds) (number)
expiresTime at which the aura will expire; can be compared to GetTime() to
determine time remaining (number)
casterUnit which applied the aura. If the aura was applied by a unit
that does not have a token but is controlled by one that does (e.g. a totem
or another player’s vehicle), returns the controlling unit. Returns nil
if the casting unit (or its controller) has no unitID. (string,unitID)
isStealable1if the aura can be transferred to a player using the Spellsteal
spell; otherwise nil (1nil)
UnitBuff
Returns information about a buff on a unit.
name, rank, icon, count, dispelType, duration, expires, caster, i
isStealable = UnitBuff(“unit“, index [, “filter“]) or i
UnitBuff(“unit“, “name“ [, “rank“ [, “filter“]])
This function is an alias for UnitAura() with a built-in HELPFUL filter (which
cannot be removed or negated with the HARMFUL filter).
Arguments:
unit—A unit to query (string,unitID)
indexIndex of an aura to query (number)
nameName of an aura to query (string)
rank (optional)Secondary text of an aura to query (often a rank; e.g. ‘‘Rank 7’’)
(string)
filter (optional)A list of filters to use separated by the pipe ‘|’character;
e.g. “RAID|PLAYER“ will query group buffs cast by the player (string)
CANCELABLEShow auras that can be cancelled
NOT_CANCELABLEShow auras that cannot be cancelled
PLAYERShow auras the player has cast
RAIDShow auras the player can cast on party/raid members (as opposed to
self buffs)
Returns:
nameName of the aura (string)
rankSecondary text for the aura (often a rank; e.g. ‘‘Rank 7’’) (string)
iconPathtoanicontexturefortheaura(string)
countThe number of times the aura has been applied (number)
dispelTypeType of aura (relevant for dispelling and certain other
mechanics); nil if not one of the following values: (string)
Curse
Disease
Magic
Poison
durationTotal duration of the aura (in seconds) (number)
expiresTime at which the aura will expire; can be compared to GetTime() to
determine time remaining (number)
Chapter 27 API Reference 965
casterUnit which applied the aura. If the aura was applied by a unit
that does not have a token but is controlled by one that does (e.g. a totem
or another player’s vehicle), returns the controlling unit. Returns nil
if the casting unit (or its controller) has no unitID. (string,unitID)
isStealable1if the aura can be transferred to a player using the Spellsteal
spell; otherwise nil (1nil)
UnitCanAssist
Returns whether one unit can assist another.
canAssist = UnitCanAssist(“unit“, “unit“)
Arguments:
unit—A unit (string,unitID)
unit—Another unit (string,unitID)
Returns:
canAssist1if the first unit can assist the second; otherwise nil (1nil)
UnitCanAttack
Returns whether one unit can attack another.
canAttack = UnitCanAttack(“unit“, “unit“)
Arguments:
unit—A unit (string,unitID)
unit—Another unit (string,unitID)
Returns:
canAttack1if the first unit can attack the second unit; otherwise nil (1nil)
UnitCanCooperate
Returns whether two units can cooperate.
canCooperate = UnitCanCooperate(“unit“, “unit“)
Two units are considered to be able to cooperate with each other if they are of
the same faction and are both players.
Arguments:
unit—A unit (string,unitID)
unit—Another unit (string,unitID)
Returns:
canCooperate1if the two units can cooperate with each other; otherwise nil
(1nil)
UnitCastingInfo
Returns information about the spell a unit is currently casting.
name, subText, text, texture, startTime, endTime, isTradeSkill, i
castID, notInterruptible = UnitCastingInfo(“unit“)
966 Part IV Reference
Arguments:
unit—A unit to query (string,unitID)
Returns:
nameName of the spell being cast (string)
subTextSecondary text associated with the spell (e.g.‘‘Rank 5’’, ‘‘Racial’’, etc.)
(string)
textText to be displayed on a casting bar (string)
texturePathtoanicontextureforthespell(string)
startTimeTime at which the cast was started (in milliseconds; can be com-
pared to GetTime() * 1000)(number)
endTimeTime at which the cast will finish (in milliseconds; can be compared
to GetTime() * 1000)(number)
isTradeSkill1if the spell being cast is a trade skill recipe; otherwise nil
(1nil)
castIDReference number for this spell; matches the 4th argument
of UNIT_SPELLCAST_* events for the same spellcast (number)
notInterruptible1if the spell can be interrupted; otherwise nil.
See the UNIT_SPELLCAST_NOT_INTERRUPTIBLE and UNIT_SPELLCAST
_INTERRUPTIBLE events for changes to this status. (1nil)
UnitChannelInfo
Returns information about the spell a unit is currently channeling.
name, subText, text, texture, startTime, endTime, isTradeSkill, i
notInterruptible = UnitChannelInfo(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
nameName of the spell being cast (string)
subTextSecondary text associated with the spell (e.g.‘‘Rank 5’’, ‘‘Racial’’, etc.)
(string)
textText to be displayed on a casting bar (string)
texturePathtoanicontextureforthespell(string)
startTimeTime at which the cast was started (in milliseconds; can be com-
pared to GetTime() * 1000)(number)
endTimeTime at which the cast will finish (in milliseconds; can be compared
to GetTime() * 1000)(number)
isTradeSkill1if the spell being cast is a trade skill recipe; otherwise nil
(1nil)
notInterruptibleIndicates that the spell cannot be interrupted,
UNIT_SPELLCAST_NOT_INTERRUPTIBLE and UNIT_SPELLCAST
_INTERRUPTIBLE are fired to indicate changes in the interruptible status.
(boolean)
Chapter 27 API Reference 967
UnitCharacterPoints
Returns the player’s number of unused talent points and profession slots.
talentPoints, professionSlots = UnitCharacterPoints(“unit“)
Arguments:
unitA unit to query; only valid for player (string,unitID)
Returns:
talentPointsNumber of unspent talent points (number)
professionSlotsNumber of available profession slots (number)
UnitClass
Returns a unit’s class.
class, classFileName = UnitClass(“unit“) or UnitClass(“name“)
The second return (classFileName) can be used for locale-independent
verification of a unit’s class, or to look up class-related data in various global
tables:
RAID_CLASS_COLORS provides a standard color for each class
(as seen in the default who, guild, calendar, and raid UIs)
CLASS_ICON_TCOORDS provides coordinates to locate each class’ icon within
the ‘‘Interface\Glues\CharacterCreate\UI-CharacterCreate-Classes’’ texture
For non-player units, the first return (class) will be the unit’s name; to always
get a localized class name regardless of unit type, use UnitClassBase
instead.
Arguments:
unit—A unit to query (string,unitID)
nameName of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
classThe localized name of the unit’s class, or the unit’s name if the unit is an
NPC (string)
classFileNameA non-localized token representing the class (string)
Example:
-- Print the name of your target in a class-specific color
local class, classFileName = UnitClass(“target“)
local color = RAID_CLASS_COLORS[classFileName]
ChatFrame1:AddMessage(class, color.r, color.g, color.b)
UnitClassBase
Returns a unit’s class.
class, classFileName = UnitClassBase(“unit“) or UnitClassBase(“name“)
968 Part IV Reference
The second return (classFileName) can be used for locale-independent
verification of a unit’s class, or to look up class-related data in various global
tables:
RAID_CLASS_COLORS provides a standard color for each class
(as seen in the default who, guild, calendar, and raid UIs)
CLASS_ICON_TCOORDS provides coordinates to locate each class’ icon within
the ‘‘Interface\Glues\CharacterCreate\UI-CharacterCreate-Classes’’ texture
Unlike UnitClass, this function returns the same values for NPCs as for
players.
Arguments:
unit—A unit to query (string,unitID)
nameName of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
classThe localized name of the unit’s class (string)
classFileNameA non-localized token representing the class (string)
UnitClassification
Returns a unit’s classification.
classification = UnitClassification(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
classificationClassification of the unit (string)
eliteElite
normal—Normal
rare—Rare
rareeliteRare-Elite
worldboss—World Boss
UnitControllingVehicle
Returns whether a unit is controlling a vehicle.
isControlling = UnitControllingVehicle(“unit“) or i
UnitControllingVehicle(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
isControllingTrue if the unit is controlling a vehicle; otherwise false
(boolean)
UnitCreatureFamily
Returns the creature family of the unit.
family = UnitCreatureFamily(“unit“)
Chapter 27 API Reference 969
Applies only to beasts of the kinds that can be taken as Hunter pets (e.g. cats,
worms, and ravagers but not zhevras, talbuks and pterrordax) and demons of
the types that can be summoned by Warlocks (e.g. imps and felguards, but not
demons that require enslaving such as infernals and doomguards or world
demons such as pit lords and armored voidwalkers).
Arguments:
unit—A unit to query (string,unitID)
Returns:
familyLocalized name of the subtype of creature (e.g. Bear, Devilsaur,
Voidwalker, Succubus), or nil if not applicable (string)
UnitCreatureType
Returns the creature type of a unit.
type = UnitCreatureType(“unit“)
Note that some creatures have no type (e.g. slimes).
Arguments:
unit—A unit to query (string,unitID)
Returns:
typeLocalized name of the type of creature (e.g. Beast, Humanoid, Undead),
or nil if not applicable (string)
UnitDamage
Returns information about the player’s or pet’s melee attack damage.
minDamage, maxDamage, minOffHandDamage, maxOffHandDamage, i
physicalBonusPos, physicalBonusNeg, percent = UnitDamage(“unit“)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
Returns:
minDamageThe unit’s minimum melee damage (number)
maxDamageThe unit’s maximum melee damage (number)
minOffHandDamageThe unit’s minimum offhand melee damage (number)
maxOffHandDamageThe unit’s maximum offhand melee damage (number)
physicalBonusPosPositive physical bonus (should be >=0) (number)
physicalBonusNegNegative physical bonus (should be <=0) (number)
percentFactor by which damage output is multiplied due to buffs/debuffs
(number)
UnitDebuff
Returns information about a debuff on a unit.
name, rank, icon, count, dispelType, duration, expires, caster, i
isStealable = UnitDebuff(“unit“, index [, “filter“]) or i
UnitDebuff(“unit“, “name“ [, “rank“ [, “filter“]])
970 Part IV Reference
This function is an alias for UnitAura() with a built-in HARMFUL filter (which
cannot be removed or negated with the HELPFUL filter).
Arguments:
unit—A unit to query (string,unitID)
indexIndex of an aura to query (number)
nameName of an aura to query (string)
rank (optional)Secondary text of an aura to query (often a rank; e.g. ‘‘Rank 7’’)
(string)
filter (optional)A list of filters to use separated by the pipe ‘|’character;
e.g. “CANCELABLE|PLAYER“ will query cancelable debuffs cast by the player
(string)
CANCELABLEShow auras that can be cancelled
NOT_CANCELABLEShow auras that cannot be cancelled
PLAYERShow auras the player has cast
RAIDShow auras the player can cast on party/raid members (as opposed to
self buffs)
Returns:
nameName of the aura (string)
rankSecondary text for the aura (often a rank; e.g. ‘‘Rank 7’’) (string)
iconPathtoanicontexturefortheaura(string)
countThe number of times the aura has been applied (number)
dispelTypeType of aura (relevant for dispelling and certain other
mechanics); nil if not one of the following values: (string)
Curse
Disease
Magic
Poison
durationTotal duration of the aura (in seconds) (number)
expiresTime at which the aura will expire; can be compared to GetTime() to
determine time remaining (number)
casterUnit which applied the aura. If the aura was applied by a unit
that does not have a token but is controlled by one that does (e.g. a totem
or another player’s vehicle), returns the controlling unit. Returns nil
if the casting unit (or its controller) has no unitID. (string,unitID)
isStealable1if the aura can be transferred to a player using the Spellsteal
spell; otherwise nil (1nil)
UnitDefense
Returns the player’s or pet’s Defense skill.
base, modifier = UnitDefense(“unit“)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
Chapter 27 API Reference 971
Returns:
baseThe unit’s base defense skill (number)
modifierTemporary modifiers to defense skill (number)
UnitDetailedThreatSituation
Returns detailed information about the threat status of one unit against
another.
isTanking, status, scaledPercent, rawPercent, threatValue = i
UnitDetailedThreatSituation(unit, mobUnit) or i
UnitDetailedThreatSituation(“name“, mobUnit)
The different values returned by this function reflect the complexity of NPC
threat management.
Raw threat roughly equates to the amount of damage a unit has caused to the
NPC plus the amount of healing the unit has performed in the NPC’s presence.
(Each quantity that goes into this sum may be modified, however; such as by a
paladin’s Righteous Fury self-buff, a priest’s Silent Resolve talent, or a player
whose cloak is enchanted with Subtlety.)
Generally, whichever unit has the highest raw threat against an NPC becomes
its primary target, and raw threat percentage simplifies this comparison.
However, most NPCs are designed to maintain some degree of target focus so
that they don’t rapidly switch targets if, for example, a unit other than the
primary target suddenly reaches 101% raw threat. The amount by which a unit
must surpass the primary target’s threat to become the new primary target
varies by distance from the NPC.
Thus, a scaled percentage value is given to provide clarity. The rawPercent
value returned from this function can be greater than 100 (indicating that unit
has greater threat against mobUnit than mobUnit’s primary target, and is thus
in danger of becoming the primary target), but the scaledPercent value will
always be 100 or lower.
Threat information for a pair of units is only returned if the player has threat
against the NPC unit in question. (For example, no threat data is provided if
the player’s pet is attacking an NPC but the player himself has taken no action,
even though the pet has threat against the NPC.)
Arguments:
unitThe unit whose threat situation is being requested (unitid)
nameThe name of a unit to query. Only valid for the player, pet, and
party/raid members. (string)
mobUnitAn NPC unit the first unit may have threat against (unitid)
Returns:
isTanking1if unit is mobUnit’s primary target, nil otherwise (1nil)
statusA threat status category (number)
0Unit has less than 100% raw threat (default UI shows no indicator)
1Unit has 100% or higher raw threat but isn’t mobUnit’s primary target
(default UI shows yellow indicator)
972 Part IV Reference
2—Unit is mobUnit’s primary target, and another unit has 100%
or higher raw threat (default UI shows orange indicator)
3—Unit is mobUnit’s primary target, and no other unit has 100% or higher
raw threat (default UI shows red indicator)
scaledPercentA percentage value representing unit’s threat against
mobUnit, scaled such that a value of 100% represents unit becoming mobUnit’s
primary target (number)
rawPercentA percentage value representing unit’s threat against
mobUnit relative to the threat of mobUnit’s primary target (number)
threatValueThe raw value of unit’s threat against mobUnit (number)
UnitExists
Returns whether a unit exists.
exists = UnitExists(“unit“) or UnitExists(“name“)
A unit ‘‘exists’’ if it can be referenced by the player; e.g. party1 exists if the
player is in a party with at least one other member (regardless of whether that
member is nearby), target exists if the player has a target, npc exists if the
player is currently interacting with an NPC, etc.
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet,npc,and
party/raid members (string)
Returns:
exists1if the unit exists, otherwise nil (1nil)
UnitFactionGroup
Returns a unit’s primary faction allegiance.
factionGroup, factionName = UnitFactionGroup(“unit“) or i
UnitFactionGroup(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
factionGroupNon-localized (English) faction name of the faction (‘‘Horde’’
or ‘‘Alliance’’) (string)
factionNameLocalized name of the faction (string)
UnitGUID
Returns a unit’s globally unique identifier.
guid = UnitGUID(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Chapter 27 API Reference 973
Returns:
guid—The units GUID (string,guid)
Example:
GUIDs are used in the combat log and in certain hyperlinks.
UnitHasRelicSlot
Returns whether a unit has a relic slot instead of a ranged weapon slot.
hasRelic = UnitHasRelicSlot(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
hasRelic1if the unit has a relic slot; otherwise nil (1nil)
UnitHasVehicleUI
Returns whether a unit is controlling a vehicle or vehicle weapon.
hasVehicle = UnitHasVehicleUI(“unit“) or UnitHasVehicleUI(“name“)
Used in the default UI to show the vehicle’s health and power status bars in
place of the controlling unit’s. Returns false for passengers riding in but not
controlling part of a vehicle; to find out whether a unit is riding in a vehicle,
use UnitInVehicle. Also note that in some vehicles the player can command
a vehicle weapon (e.g. gun turret) without controlling the vehicle itself; to find
out whether a unit is controlling a vehicle, use UnitControllingVehicle.
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
hasVehicleTrue if the unit is controlling a vehicle or vehicle weapon; other-
wise false (boolean)
UnitHealth
Returns a unit’s current amount of health.
health = UnitHealth(“unit“) or UnitHealth(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
healthThe unit’s current amount of health (hit points) (number)
UnitHealthMax
Returns a unit’s maximum health value.
maxValue = UnitHealthMax(“unit“) or UnitHealthMax(“name“)
974 Part IV Reference
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
maxValueThe unit’s maximum health (hit points) (number)
UnitInBattleground
Returns whether a unit is in same battleground instance as the player.
raidNum = UnitInBattleground(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
raidNumNumeric portion of the unit’s raid unitID (e.g. 13 for raid13)
(number)
UnitInParty
Returns whether a unit is a player unit in the player’s party.
inParty = UnitInParty(“unit“) or UnitInParty(“name“)
Always returns 1 for the player unit. Returns nil for the player’s or party
members’ pets.
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query (string)
Returns:
inParty1if the unit is a player unit in the player’s party; otherwise nil.
(1nil)
UnitInRaid
Returns whether a unit is in the player’s raid.
inRaid = UnitInRaid(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
inRaidIndex of the unit in the raid (matches the numeric part of the unit’s
raid unitID minus 1; e.g. returns 0 for raid1,12forraid13,etc)(number)
UnitInRange
Returns whether a party/raid member is nearby.
inRange = UnitInRange(“unit“) or UnitInRange(“name“)
The range check used by this function isn’t directly based on the player’s
abilities (which may have varying ranges); it’s fixed by Blizzard at a distance of
around 40 yards (which encompasses many common healing spells and other
abilities often used on raid members).
Also returns nil for units outside the player’s area of view.
Chapter 27 API Reference 975
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for party/raid members and their
pets (string)
Returns:
inRange1if the unit is close enough to the player to (likely) be in range for
helpful spells; otherwise nil (1nil)
UnitInVehicle
Returns whether a unit is in a vehicle.
inVehicle = UnitInVehicle(“unit“) or UnitInVehicle(“name“)
A unit can be riding in a vehicle without controlling it: to test whether a unit is
controlling a vehicle, use UnitControllingVehicle or UnitHasVehicleUI.
Note: multi-passenger mounts appear as vehicles for passengers but not for the
owner.
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
inVehicle1if the unit is in a vehicle; otherwise nil (1nil)
UnitInVehicleControlSeat
Returns whether a unit controls a vehicle.
isInControl = UnitInVehicleControlSeat()
Returns:
isInControlTrue if the unit controls a vehicle (boolean)
UnitIsAFK
Returns whether a unit is marked AFK (Away From Keyboard).
isAFK = UnitIsAFK(“unit“) or UnitIsAFK(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
isAFK1if the unit is AFK; otherwise nil (1nil)
UnitIsCharmed
Returns whether a unit is currently charmed.
isCharmed = UnitIsCharmed(“unit“)
A charmed unit is affected by Mind Control (or a similar effect) and thus
hostile to units which are normally his or her allies.
976 Part IV Reference
Arguments:
unit—A unit to query (string,unitID)
Returns:
isCharmed1if the unit is charmed; otherwise nil (1nil)
UnitIsConnected
Returns whether a unit is connected (i.e. not Offline).
isConnected = UnitIsConnected(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
isConnected1if the player is connected; otherwise nil (1nil)
UnitIsControlling
Returns whether a unit is controlling another unit.
isControlling = UnitIsControlling(“unit“)
Applies to Mind Control and similar cases as well as to players piloting
vehicles.
Arguments:
unit—A unit to query (string,unitID)
Returns:
isControlling1if the unit is controlling another unit; otherwise nil (1nil)
UnitIsCorpse
Returns whether a unit is a corpse.
isCorpse = UnitIsCorpse(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
isCorpse1if the unit is a corpse; otherwise nil (1nil)
UnitIsDND
Returns whether a unit is marked DND (Do Not Disturb).
isDND = UnitIsDND(“unit“) or UnitIsDND(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
isDND1if the unit is marked Do Not Disturb, otherwise nil (1nil)
UnitIsDead
Returns whether a unit is dead.
isDead = UnitIsDead(“unit“)
Chapter 27 API Reference 977
Only returns 1 while the unit is dead and has not yet released his or her spirit.
See UnitIsGhost() for after the unit has released.
Arguments:
unit—A unit to query (string,unitID)
Returns:
isDead1if the unit is dead; otherwise nil (1nil)
Example:
-- Scan your party or raid and count how many people are dead
local maxNum = GetNumRaidMembers()
local unitType = “raid“
if maxNum <= 0 then
maxNum = GetNumPartyMembers()
unitType = “party“
end
if maxNum > 0 then
local deadCount = 0
for i=1,maxNum do
if UnitIsDead(unitType .. i) then
deadCount = deadCount + 1
end
end
print(“There are “ .. deadCount .. “ people dead in your “ i
.. unitType)
else
print(“You are not in a party or raid“)
end
UnitIsDeadOrGhost
Returns whether a unit is either dead or a ghost.
isDeadOrGhost = UnitIsDeadOrGhost(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
isDeadOrGhost1if the unit is dead or a ghost, otherwise nil (1nil)
UnitIsEnemy
Returns whether two units are enemies.
isEnemy = UnitIsEnemy(“unit“, “unit“)
Arguments:
unit—A unit (string,unitID)
unit—Another unit (string,unitID)
Returns:
isEnemy1if the units are enemies; otherwise nil (1nil)
978 Part IV Reference
UnitIsFeignDeath
Returns whether a unit is feigning death.
isFeign = UnitIsFeignDeath(“unit“)
Only provides valid data for friendly units.
Arguments:
unit—A unit to query (string,unitID)
Returns:
isFeign1if the unit is feigning death; otherwise nil (1nil)
UnitIsFriend
Returns whether two units are friendly.
isFriends = UnitIsFriend(“unit“, “unit“)
Arguments:
unit—A unit (string,unitID)
unit—Another unit (string,unitID)
Returns:
isFriends1if the two units are friendly; otherwise nil (1nil)
UnitIsGhost
Returns whether a unit is currently a ghost.
isGhost = UnitIsGhost(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
isGhost1if the unit is a ghost; otherwise nil (1nil)
UnitIsInMyGuild
Returns whether a unit is in the player’s guild.
inGuild = UnitIsInMyGuild(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
inGuild1if the unit is in the player’s guild; otherwise nil (1nil)
UnitIsPVP
Returns whether a unit is flagged for PvP activity.
isPVP = UnitIsPVP(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
isPVP1if the unit is flagged for PVP activity; otherwise nil (1nil)
Chapter 27 API Reference 979
UnitIsPVPFreeForAll
Returns whether a unit is flagged for free-for-all PvP.
isFreeForAll = UnitIsPVPFreeForAll(“unit“)
Free-for-all PvP allows all players to attack each other regardless of faction;
used in certain outdoor areas (such as Gurubashi Arena and ‘‘The Maul’’
outside Dire Maul).
Arguments:
unit—A unit to query (string,unitID)
Returns:
isFreeForAll1if the unit is enabled for free-for-all PvP; otherwise nil
(1nil)
UnitIsPVPSanctuary
Returns whether a unit is in a Sanctuary area preventing PvP activity.
state = UnitIsPVPSanctuary(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
state1if the unit is in a PVP Sanctuary; otherwise nil (1nil)
UnitIsPartyLeader
Returns whether a unit is the leader of the player’s party.
leader = UnitIsPartyLeader(“unit“) or UnitIsPartyLeader(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query (string)
Returns:
leader1if the unit is the party leader; otherwise nil (1nil)
UnitIsPlayer
Returns whether a unit is a player unit (not an NPC).
isPlayer = UnitIsPlayer(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
isPlayer1if the unit is a player unit; otherwise nil (1nil)
UnitIsPossessed
Returns whether a unit is possessed by another.
isPossessed = UnitIsPossessed(“unit“)
Arguments:
unit—A unit to query (string,unitID)
980 Part IV Reference
Returns:
isPossessed1if the given unit is possessed; otherwise nil (1nil)
UnitIsRaidOfficer
Returns whether a unit is a raid assistant in the player’s raid.
leader = UnitIsRaidOfficer(“unit“) or UnitIsRaidOfficer(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query (string)
Returns:
leader1if the unit is a raid assistant; otherwise nil (1nil)
UnitIsSameServer
Returns whether two units are from the same server.
isSame = UnitIsSameServer(“unit“, “unit“)
Only meaningful in cross-realm battlegrounds.
Arguments:
unit—A unit (string,unitID)
unit—Another unit (string,unitID)
Returns:
isSame1if the two units are from the same server; otherwise nil.(1nil)
UnitIsSilenced
Returns whether a character is silenced on a voice channel.
silenced = UnitIsSilenced(“name“, “channel“)
Arguments:
nameName of a character (string)
channelName of a chat channel (string)
Returns:
silenced1if the unit is silenced on the given channel; otherwise nil (1nil)
UnitIsTalking
Returns whether a unit is currently speaking in voice chat.
state = UnitIsTalking(“unit“)
Despite the ‘‘unit’’ name, this function only accepts player names, not unitIDs.
Arguments:
unitName of a character in the player’s current voice channel (string)
Returns:
state1if the unit is currently speaking in voice chat; otherwise nil (1nil)
UnitIsTapped
Returns whether a unit is tapped.
UnitIsTapped(unit)
Chapter 27 API Reference 981
Normally, rewards for killing a unit are available only to the character or
group who first damaged the unit; once a character has thus established his
claim on the unit, it is considered ‘‘tapped’’.
Arguments:
unitThe unitid to query (unitId)
UnitIsTappedByAllThreatList
Returns whether a unit allows all players on its threat list to receive kill credit.
allTapped = UnitIsTappedByAllThreatList(“unit“)
Used to override the normal ‘‘tapping’’ behavior for certain mobs. If this
function returns 1, the player does not have to be the first to attack the mob (or
in the same party/raid as the first player to attack) in order to receive quest or
achievement credit for killing it.
In the default UI, this function can prevent the graying of a unit’s name
background in the TargetFrame and FocusFrame even if the unit is otherwise
tapped, indicating that kill credit is still available if the player attacks.
Arguments:
unit—A unit to query (string,unitID)
Returns:
allTapped1if the unit allows all players on its threat list to receive kill credit;
otherwise nil (1nil)
UnitIsTappedByPlayer
Returns whether a unit is tapped by the player or the player’s group.
isTapped = UnitIsTappedByPlayer(“unit“)
Normally, rewards for killing a unit are available only to the character or
group who first damaged the unit; once a character has thus established his
claim on the unit, it is considered ‘‘tapped’’.
Arguments:
unitThe unit to be queried (string)
Returns:
isTapped1if the unit is tapped by the player; otherwise nil (1nil)
UnitIsTrivial
Returns whether a unit is trivial at the player’s level.
isTrivial = UnitIsTrivial(“unit“)
Killing trivial units (whose level is colored gray in the default UI) does not
reward honor or experience.
Arguments:
unit—A unit to query (string,unitID)
Returns:
isTrivial1if the unit is trivial at the player’s level; otherwise nil (1nil)
982 Part IV Reference
UnitIsUnit
Returns whether two unit references are to the same unit.
isSame = UnitIsUnit(“unit“, “unit“)
Useful for determining whether a composite unitID (such as raid19target)
also refers to a basic unitID; see example.
Arguments:
unit—A unit (string,unitID)
unit—Another unit (string,unitID)
Returns:
isSame—Returns 1if the two references are to the same unit; otherwise nil
(1nil)
Example:
if (UnitIsUnit(“targettarget“,“player“))
-- watch out! your target is also targeting you!
end
UnitIsVisible
Returns whether a unit is in the player’s area of interest.
isVisible = UnitIsVisible(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
isVisible1if the unit is is in the player’s area of interest; otherwise nil
(1nil)
UnitLevel
Returns a unit’s level.
level = UnitLevel(“unit“)
Returns -1 for boss units and hostile units whose level is ten levels or more
above the player’s.
Arguments:
unit—A unit to query (string,unitID)
Returns:
levelThe unit’s level (number)
UnitName
Returns the name of a unit.
name, realm = UnitName(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Chapter 27 API Reference 983
Returns:
name—Name of the unit (string)
realmName of the unit’s home realm if the unit is not from the player’s realm;
otherwise nil (string)
Example:
-- Send a chat message to the player that’s you are currently mousing
-- over. This should be run as a macro (via keybind) so your mouse can
-- be hovering over a unit in the 3-D world, or a unit frame
local name = UnitName(“mouseover“)
SendChatMessage(“Hey “ .. name .. “ I’m mousing over you!!!“, i
“WHISPER“, nil, name)
-- This can be run as a macro by putting it all on one line, and adding
-- run in front of it, like so:
--
-- /run local name = UnitName(“mouseover“); SendChatMessage(“Hey “ i
.. name .. “ I’m mousing over you!!!“, “WHISPER“, nil, name)
UnitOnTaxi
Returns whether a unit is currently riding a flight path (taxi).
onTaxi = UnitOnTaxi(“unit“)
Valid for any unit in the player’s area of interest, but generally useful only for
player. Taxi flights move quickly, so a taxi-riding unit visible to the player
will not remain visible for very long.
Arguments:
unit—A unit to query (string,unitID)
Returns:
onTaxi1if the unit is on a taxi; otherwise nil (1nil)
UnitPVPName
Returns the name of a unit including the unit’s current title.
name = UnitPVPName(“unit“)
Titles are no longer specific to PvP; this function returns a unit’s name with
whichever title he or she is currently displaying (e.g. ‘‘Gladiator Spin’’,
‘‘Keydar Jenkins’’, ‘‘Ownsusohard, Champion of the Frozen Wastes’’, etc).
Arguments:
unit—A unit to query (string,unitID)
Returns:
nameName of the unit including the unit’s current title (string)
UnitPlayerControlled
Returns whether a unit is controlled by a player.
isPlayer = UnitPlayerControlled(“unit“)
984 Part IV Reference
Arguments:
unit—A unit to query (string,unitID)
Returns:
isPlayer1if the unit is controlled by a player; otherwise nil (1nil)
UnitPlayerOrPetInParty
Returns whether a unit is in the player’s party or belongs to a party member.
inParty = UnitPlayerOrPetInParty(“unit“) or i
UnitPlayerOrPetInParty(“name“)
Returns nil for the player and the player’s pet.
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query (string)
Returns:
inParty1if the unit is in the player’s party or is a pet belonging to a party
member; otherwise nil (1nil)
UnitPlayerOrPetInRaid
Returns whether a unit is in the player’s raid or belongs to a raid member.
inParty = UnitPlayerOrPetInRaid(“unit“) or UnitPlayerOrPetInRaid
(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query (string)
Returns:
inParty1if the unit is in the player’s raid or is a pet belonging to a raid mem-
ber; otherwise nil (1nil)
UnitPower
Returns a unit’s current level of mana, rage, energy or other power type.
power = UnitPower(“unitID“ [, “powerType“])
Returns zero for non-existent units.
Arguments:
unitID—A unit to query (string,unitID)
powerType (optional)A specific power type to query (string, powerType)
Returns:
powerThe unit’s current level of mana, rage, energy, runic power, or other
power type (unitID)
UnitPowerMax
Returns a unit’s maximum mana, rage, energy or other power type.
maxValue = UnitPowerMax(“unitID“ [, powerType])
Chapter 27 API Reference 985
Returns the unit’s current maximum power, if the unit does not exist then zero
is returned.
When querying with a powerType, as long as the unit exists you will get the
maximum untalented power even if the class does not use the power type.
Arguments:
unitID—A unit to query (string,unitID)
powerType (optional)Specific power type to query for the unit (number,pow-
erType)
Returns:
maxValueThe unit’s maximum mana, rage, energy, or other power (number)
UnitPowerType
Returns the power type (energy, mana, rage) of the given unit.
powerType, powerToken, altR, altG, altB = UnitPowerType(“unit“) or i
UnitPowerType(“name“)
Does not return color values for common power types (mana, rage, energy,
focus, and runic power); the canonical colors for these can be found in the
PowerBarColor table. Color values may be included for special power types
such as those used by vehicles.
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
powerTypeA number identifying the power type (number)
0—Mana
1—Rage
2—Focus
3—Energy
6Runic Power
powerTokenThe name of a global variable containing the localized name of
the power type (string)
altRRed component of the color used for displaying this power type
(number)
altGGreen component of the color used for displaying this power type
(number)
altBBlue component of the color used for displaying this power type
(number)
UnitRace
Returns the name of a unit’s race.
race, fileName = UnitRace(“unit“)
Arguments:
unit—A unit to query (string,unitID)
986 Part IV Reference
Returns:
raceLocalized name of the unit’s race (string)
fileNameA non-localized token representing the unit’s race (string)
UnitRangedAttack
Returns information about the player’s or pet’s ranged weapon skill.
rangedAttackBase, rangedAttackMod = UnitRangedAttack(“unit“)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
Returns:
rangedAttackBaseThe unit’s base ranged weapon skill (number)
rangedAttackModTemporary modifiers to ranged weapon skill (number)
UnitRangedAttackPower
Returns the player’s or pet’s ranged attack power.
base, posBuff, negBuff = UnitRangedAttackPower(“unit“)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
Returns:
baseBase ranged attack power (number)
posBuffPositive buffs to ranged attack power (number)
negBuffNegative buffs to ranged attack power (number)
UnitRangedDamage
Returns information about the player’s or pet’s ranged attack damage and
speed.
rangedAttackSpeed, minDamage, maxDamage, physicalBonusPos, i
physicalBonusNeg, percent = UnitRangedDamage(“unit“)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
Returns:
rangedAttackSpeedCurrent speed of the unit’s ranged attack
(attacks per second), or 0 if no ranged weapon is equipped (number)
minDamageThe minimum base damage per attack (number)
maxDamageThe maximum base damage per attack (number)
physicalBonusPosPositive modifiers to ranged weapon damage (number)
physicalBonusNegNegative modifiers to ranged weapon damage (number)
percentFactor by which damage output is multiplied due to buffs/debuffs
(number)
UnitReaction
Returns the reaction of one unit with regards to another as a number.
reaction = UnitReaction(“unit“, “unit“)
Chapter 27 API Reference 987
The returned value often (but not always) matches the unit’s level of
reputation with the second unit’s faction, and can be used with the
UnitReactionColor global table to return the color used to display a unit’s
reaction in the default UI.
Arguments:
unit—A unit (string,unitID)
unit—Another unit (string,unitID)
Returns:
reactionReaction of the first unit towards the second unit (number)
1—Hated
2Hostile
3—Unfriendly
4—Neutral
5—Friendly
6Honored
7Revered
8—Exalted
UnitResistance
Returns information about the player’s or pet’s magic resistance.
base, resistance, positive, negative = UnitResistance(“unit“,
resistanceIndex)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
resistanceIndexIndex of a magic resistance type (number)
1—Fire
2—Nature
3—Frost
4Shadow
5—Arcane
Returns:
baseBase resistance value (generally 0) (number)
resistanceCurrent resistance value (including modifiers) (number)
positivePositive resistance modifiers (number)
negativeNegative resistance modifiers (number)
UnitSelectionColor
Returns a color indicating hostility and related status of a unit.
red, green, blue, alpha = UnitSelectionColor(“unit“) or i
UnitSelectionColor(“name“)
This color is used in various places in the default UI, such as the background
behind a unit’s name in the target and focus frames. For NPCs, the color
reflects hostility and reputation, ranging from red (hostile) to orange or yellow
(unfriendly or neutral) to green (friendly). When the unit is a player, a blue
color is used unless the player is active for PvP, in which case the color may be
red (he can attack you and you can attack him), yellow (you can attack him but
he can’t attack you) or green (ally). Color component values are floating point
numbers between 0 and 1.
Arguments:
unit—A unit to query (string,unitID)
988 Part IV Reference
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
redThe red component of the color. (number)
greenThe green component of the color. (number)
blueThe blue component of the color. (number)
alphaThe alpha (opacity) component of the color. (number)
UnitSex
Returns the gender of the given unit or player.
gender = UnitSex(“unit“) or UnitSex(“name“)
Arguments:
unit—A unit to query (string,unitID)
nameThe name of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
genderThe unit’s gender (number)
1—Neuter / Unknown
2—Male
3—Female
UnitStat
Returns information about a basic character statistic for the player or pet.
stat, effectiveStat, posBuff, negBuff = UnitStat(“unit“, statIndex)
Arguments:
unitA unit to query; only valid for player or pet (string,unitID)
statIndexIndex of a basic statistic (number)
1—Strength
2Agility
3—Stamina
4Intellect
5—Spirit
Returns:
statCurrent value of the statistic (number)
effectiveStatEffective value of the statistic (number)
posBuffPositive modifiers to the statistic (number)
negBuffNegative modifiers to the statistic (number)
UnitSwitchToVehicleSeat
Moves the player to another seat within his current vehicle.
UnitSwitchToVehicleSeat(“unit“, seat)
Arguments:
unitUnit to move (only valid for player)(string,unitID)
seatIndex of a seat to switch to (number)
Chapter 27 API Reference 989
UnitTargetsVehicleInRaidUI
Returns whether attempts to target a unit should target its vehicle.
targetVehicle = UnitTargetsVehicleInRaidUI(“unit“)
The unit can still be targeted: this flag is used to provide a convenience in the
default UI for certain cases (such as the Malygos encounter) such that clicking a
unit in the raid UI targets its vehicle (e.g. so players can use their drakes to heal
other players’ drakes).
Arguments:
unit—A unit to query (string,unitID)
Returns:
targetVehicleTrue if clicking the unit’s raid UI representation should tar-
get the unit’s vehicle instead of the unit itself; otherwise false (boolean)
UnitThreatSituation
Returns the general threat status of a unit.
status = UnitThreatSituation(unit [, mobUnit]) or i
UnitThreatSituation(“name“ [, mobUnit])
See UnitDetailedThreatSituation for details about threat values.
Threat information for a pair of units is only returned if the player has threat
against the NPC unit in question. (For example, no threat data is provided if
the player’s pet is attacking an NPC but the player himself has taken no action,
even though the pet has threat against the NPC.)
Arguments:
unitThe unit whose threat situation is being requested (unitid)
nameThe name of a unit to query. Only valid for the player, pet, and
party/raid members. (string)
mobUnit (optional)An NPC unit the first unit may have threat against; if nil,
returned values reflect whichever NPC unit the first unit has the highest threat
against. (unitid)
Returns:
statusA threat status category (number)
0Unit has less than 100% raw threat (default UI shows no indicator)
1Unit has 100% or higher raw threat but isn’t mobUnit’s primary target
(default UI shows yellow indicator)
2—Unit is mobUnit’s primary target, and another unit has 100%
or higher raw threat (default UI shows orange indicator)
3—Unit is mobUnit’s primary target, and no other unit has 100% or higher
raw threat (default UI shows red indicator)
UnitUsingVehicle
Returns whether a unit is using a vehicle.
usingVehicle = UnitUsingVehicle(“unit“)
990 Part IV Reference
Unlike similar functions, UnitUsingVehicle() also returns true while the
unit is transitioning between seats in a vehicle.
Arguments:
unit—A unit to query (string,unitID)
Returns:
usingVehicle1if the unit is using a vehicle; otherwise nil (1nil)
UnitVehicleSeatCount
Returns the number of seats in a unit’s vehicle.
numSeats = UnitVehicleSeatCount(“unit“)
Note: returns 0 for multi-passenger mounts even though multiple seats are
available.
Arguments:
unit—A unit to query (string,unitID)
Returns:
numSeatsNumber of seats in the unit’s vehicle (number)
UnitVehicleSeatInfo
Returns information about seats in a vehicle.
controlType, occupantName, occupantRealm, canEject, i
canSwitchSeats = UnitVehicleSeatInfo(“unit“, seat)
Note: multi-passenger mounts appear as vehicles for passengers but not for the
owner; seat information applies only to the passenger seats.
Arguments:
unit—A unit to query (string,unitID)
seatIndex of a seat in the unit’s vehicle (number)
Returns:
controlTypeType of control for the seat (string)
ChildUnit in this seat controls part of the vehicle but not its movement
(e.g. a gun turret)
NoneUnit in this seat has no control over the vehicle
RootUnit in this seat controls the movement of the vehicle
occupantNameName of the unit in the seat, or nil if the seat is empty
(string)
occupantRealmHome realm of the unit in the seat; nil if the seat is
empty or its occupant is from the same realm as the player (string)
canEjectTrue if the vehicle’s driver can eject the occupant of the seat
(boolean)
canSwitchSeatsTrue if the player can switch to this seat. (boolean)
UnitVehicleSkin
Returns the style of vehicle UI to display for a unit.
skin = UnitVehicleSkin(“unit“) or UnitVehicleSkin(“name“)
Chapter 27 API Reference 991
Arguments:
unit—A unit to query (string,unitID)
nameName of a unit to query; only valid for player,pet, and party/raid
members (string)
Returns:
skinToken identifying the style of vehicle UI to display for the unit (string)
MechanicalUsed for mechanical vehicles
NaturalUsed for creature mounts
UnitXP
Returns the player’s current amount of experience points.
currXP = UnitXP(“unit“)
Arguments:
unitA unit to query; only valid for player (string,unitID)
Returns:
currXPCurrent amount of experience points (number)
UnitXPMax
Return the total amount of experience points required for the player to gain a
level.
playerMaxXP = UnitXPMax(“unit“)
Arguments:
unitA unit to query; only valid for player (string,unitID)
Returns:
playerMaxXPTotal amount of experience points required for the player to
gain a level (number)
UnstablePet
Makes a pet from the stables the active pet.
UnstablePet(index)
If another pet is already active, it will be placed in the stables.
Arguments:
indexIndex of a stable slot (between 1and GetNumStablePets()) (number)
UpdateAddOnCPUUsage
Updates addon CPU profiling information.
Only has effect if the scriptProfile CVar is set to 1. See
GetAddOnCPUUsage() for the updated data.
UpdateAddOnMemoryUsage
Updates addon memory usage information.
See GetAddOnMemoryUsage() for the updated data.
Protected UpdateGMTicket
Updates the open GM ticket with new text.
UpdateGMTicket(“text“)
992 Part IV Reference
Arguments:
textNew text for the ticket (string)
UpdateMapHighlight
Returns information about the texture used for highlighting zones in a
continent map on mouseover.
name, fileName, texCoordX, texCoordY, textureX, textureY, i
scrollChildX, scrollChildY = UpdateMapHighlight(cursorX, cursorY)
Arguments:
cursorXHorizontal position of the mouse cursor relative to the
current world map (0 =left edge, 1=right edge) (number)
cursorYVertical position of the unit relative to the current world map (0 =
top, 1=bottom) (number)
Returns:
nameThe name of the zone being highlighted (string)
fileNameUnique part of the path to the highlight texture for the
zone; full path follows the format “Interface\\WorldMap\\“
..fileName..“\\“..fileName..“Highlight“ (string)
texCoordXRight texCoord value for the highlight texture (number)
texCoordYBottom texCoord value for the highlight texture (number)
textureXWidth of the texture as a proportion of the world map’s width
(number)
textureYHeight of the texture as a proportion of the world map’s height
(number)
scrollChildXHorizontal position of the texture’s top left corner relative
to the current world map (0 =left edge, 1=right edge) (number)
scrollChildYVertical position of the texture’s top left corner rel-
ative to the current world map (0 =top, 1=bottom) (number)
UpdateSpells
Requests spellbook information from the server.
The UPDATE_SPELLS event fires when new spellbook information is available.
UploadSettings
Stores a backup of game settings on the server.
Does nothing unless server-side settings have been disabled by setting the
synchronizeSettings CVar to 0.
Protected UseAction
Uses an action.
UseAction(slot [, “target“ [, “button“]])
Arguments:
slotAn action bar slot (number,actionID)
target (optional)A unit to be used as target for the action (string,unitID)
Chapter 27 API Reference 993
button (optional)Mouse button used to activate the action (string)
Button4Fourth mouse button
Button5Fifth mouse button
LeftButtonLeft mouse button (also used when the action is activated via
keyboard)
MiddleButtonThird mouse button (typically middle button/scroll wheel)
RightButtonRight mouse button
Protected UseContainerItem
Activate (as with right-clicking) an item in one of the player’s bags.
UseContainerItem(container, slot [, “target“])
Has the same effect as right-clicking an item in the default UI; therefore, results
may vary by context. In cases of conflict, conditions listed first override those
below:
If the bank or guild bank UI is open, moves the item into the bank or guild
bank (or if the item is in the bank or guild bank, moves it into the player’s
inventory).
If the trade UI is open, puts the item into the first available trade slot
(or if the item is soulbound, into the ‘‘will not be traded’’ slot).
If the merchant UI is open and not in repair mode, attempts to sell the item to
the merchant.
If the Send Mail UI is open, puts the item into the first available slot for mes-
sage attachments.
If an item is readable (e.g. Lament of the Highborne), opens it for reading.
If an item is lootable (e.g. Magically Wrapped Gift), opens it for looting
If an item can be equipped, attempts to equip the item (placing any cur-
rently equipped item of the same type into the container slot used).
If an item has a ‘‘Use:’’ effect, activates said effect. Under this condition
only, the function is protected and can only be called by the Blizzard UI.
If none of the above conditions are true, nothing happens.
Arguments:
containerIndex of one of the player’s bags or other containers (number,con-
tainerID)
slotIndex of an item slot within the container (number, containerSlotID)
target (optional)A unit to be used as target for the action (string,unitID)
UseEquipmentSet
Equips the items in an equipment set.
equipped = UseEquipmentSet(“name“)
Arguments:
nameName of an equipment set (case sensitive) (string)
994 Part IV Reference
Returns:
equippedtrue if the set was equipped; otherwise nil (boolean)
Protected UseInventoryItem
Activate (as with right-clicking) an equipped item.
UseInventoryItem(slot)
If the inventoryID passed refers to an empty slot or a slot containing an item
without a ‘‘Use:’’ action, this function is not protected (i.e. usable only by the
Blizzard UI), but also has no effect.
Arguments:
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
Protected UseItemByName
Uses an arbitrary item (optionally on a specified unit).
UseItemByName(itemID [, “target“]) or UseItemByName(“itemName“ i
[, “target“]) or UseItemByName(“itemLink“ [, “target“])
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
target (optional)A unit on which to use the item, if applicable (string,
unitID)
Protected UseQuestLogSpecialItem
Uses the item associated with a current quest.
UseQuestLogSpecialItem(questIndex)
Available for a number of quests which involve using an item (i.e. ‘‘Use the
MacGuffin to summon and defeat the boss’’, ‘‘Use this saw to fell 12 trees’’,
etc.)
Arguments:
questIndexIndex of a quest log entry with an associated usable item
(between 1and GetNumQuestLogEntries())(number)
UseSoulstone
Instantly resurrects the player in place, if possible.
Usable if the player is dead (and has not yet released his or her spirit to the
graveyard) and has the ability to instantly resurrect (provided by a Warlock’s
Soulstone or a Shaman’s Reincarnation passive ability).
VehicleAimDecrement
Adjusts vehicle aim downward by a specified amount.
VehicleAimDecrement(amount)
Arguments:
amountAngle by which to adjust aim (in radians) (number)
Chapter 27 API Reference 995
Protected VehicleAimDownStart
Starts adjusting vehicle aim downward.
Protected VehicleAimDownStop
Stops adjusting vehicle aim downward.
VehicleAimGetAngle
Returns the aim angle of a vehicle weapon.
angle = VehicleAimGetAngle()
The returned value is in radians, with positive values indicating upward angle,
negative values indicating downward angle, and 0 indicating straight ahead.
Returns:
angleVertical angle of vehicle weapon aim (in radians) (number)
VehicleAimGetNormAngle
Returns the aim angle of a vehicle weapon relative to its minimum angle.
angle = VehicleAimGetNormAngle()
The returned value is in radians, with 0 indicating the lowest angle allowed for
the vehicle weapon and increasing values for upward aim.
Returns:
angleVertical angle of vehicle weapon aim (in radians) (number)
VehicleAimIncrement
Adjusts vehicle aim upward by a specified amount.
VehicleAimIncrement(amount)
Arguments:
amountAngle by which to adjust aim (in radians) (number)
VehicleAimRequestAngle
Attempts to set a vehicle weapon’s aim angle to a specific value.
VehicleAimRequestAngle(amount)
Causes aim angle to transition smoothly from the current value to the
requested value (or to the closest allowed value to the requested value if it is
beyond the vehicle’s limits).
Aim angle values are in radians, with positive values indicating upward angle,
negative values indicating downward angle, and 0 indicating straight ahead.
Arguments:
amountNew aim angle (in radians) (number)
VehicleAimRequestNormAngle
Attempts to set a vehicle weapon’s aim angle to a specific value relative to its
minimum value.
VehicleAimRequestNormAngle(amount)
996 Part IV Reference
Causes aim angle to transition smoothly from the current value to the
requested value (or to the closest allowed value to the requested value if it is
beyond the vehicle’s limits).
The returned value is in radians, with 0 indicating the lowest angle allowed for
the vehicle weapon and increasing values for upward aim.
Arguments:
amountNew aim angle (in radians) (number)
Protected VehicleAimUpStart
Starts adjusting vehicle aim upward.
Protected VehicleAimUpStop
Stops adjusting vehicle aim upward.
VehicleCameraZoomIn
Zooms the player’s view in while in a vehicle.
VehicleCameraZoomOut
Zooms the player’s view out while in a vehicle.
VehicleExit
Removes the player from the current vehicle.
Does nothing if the player is not in a vehicle.
VehicleNextSeat
Moves the player from his current seat in a vehicle to the next sequentially
numbered seat.
If the player is in the highest-numbered seat, cycles around to the
lowest-numbered seat.
VehiclePrevSeat
Moves the player from his current seat in a vehicle to the previous sequentially
numbered seat.
If the player is in the lowest-numbered seat, cycles around to the
highest-numbered seat.
VoiceChat_GetCurrentMicrophoneSignalLevel
Returns the current volume level of the microphone signal.
volume = VoiceChat_GetCurrentMicrophoneSignalLevel()
Returns:
volumeThe current volume level of the microphone signal (number)
VoiceChat_IsPlayingLoopbackSound
Returns whether the Microphone Test recording is playing.
VoiceChat_IsPlayingLoopbackSound(isPlaying)
Arguments:
isPlaying1if the loopback sound is currently being played; otherwise nil
(number)
Chapter 27 API Reference 997
VoiceChat_IsRecordingLoopbackSound
Returns whether a Microphone Test is recording.
isRecording = VoiceChat_IsRecordingLoopbackSound()
Returns:
isRecording1if the player is recording a voice sample, otherwise 0 (number)
Example:
-- Print a message indicating your recording status
local insertString = ““
if VoiceChat_IsRecordingLoopbackSound() == 0 then
insertString = “not “
end
DEFAULT_CHAT_FRAME:AddMessage(“You are “..insertString.. i
“currently recording a sound sample.“)
VoiceChat_PlayLoopbackSound
Plays back the Microphone Test recording.
VoiceChat_RecordLoopbackSound
Begins recording a Microphone Test.
VoiceChat_RecordLoopbackSound(seconds)
Arguments:
secondsThe amount of time to record (in seconds) (number)
VoiceChat_StopPlayingLoopbackSound
Stops playing the Microphone Test recording.
VoiceChat_StopRecordingLoopbackSound
Stops recording a Microphone Test.
VoiceEnumerateCaptureDevices
Returns the name of an audio input device for voice chat.
deviceName = VoiceEnumerateCaptureDevices(deviceIndex)
Arguments:
deviceIndexIndex of the device (between 1and Sound_ChatSystem_Get
NumInputDrivers())(number)
Returns:
deviceName—Name of the device (string)
VoiceEnumerateOutputDevices
Returns the name of an audio output device for voice chat.
device = VoiceEnumerateOutputDevices(deviceIndex)
Arguments:
deviceIndexIndex of the device (between 1and Sound_ChatSystem_Get
NumOutputDrivers())(number)
Returns:
device—Name of the device (string)
998 Part IV Reference
VoiceGetCurrentCaptureDevice
Returns the index of the current voice capture device.
index = VoiceGetCurrentCaptureDevice()
Returns:
indexIndex of the current voice capture device (between 1and
Sound_ChatSystem_GetNumInputDrivers())(number)
VoiceGetCurrentOutputDevice
Returns the index of the current voice output device.
index = VoiceGetCurrentOutputDevice()
Returns:
indexIndex of the current voice output device (between 1and
Sound_ChatSystem_GetNumOutputDrivers())(number)
VoiceIsDisabledByClient
Returns whether the voice chat system cannot be enabled.
isDisabled = VoiceIsDisabledByClient()
Voice chat may be disabled if the underlying hardware does not support it or if
multiple instances of World of Warcraft are running on the same hardware.
Returns:
isDisabled1if the voice system is disabled; otherwise nil (1nil)
VoiceSelectCaptureDevice
Selects an audio input device for voice chat.
VoiceSelectCaptureDevice(“deviceName“)
Arguments:
deviceNameName of an audio input device, as returned from
VoiceEnumerateCaptureDevices() (string)
VoiceSelectOutputDevice
Selects an audio output device for voice chat.
VoiceSelectOutputDevice(“deviceName“)
Arguments:
deviceNameName of an audio output device, as returned from
VoiceEnumerateOutputDevices() (string)
Confirmation WithdrawGuildBankMoney
Attempts to withdraw money from the guild bank.
WithdrawGuildBankMoney(amount)
Causes a PLAYER_MONEY event to fire, indicating the amount withdrawn has
been added to the player’s total (see GetMoney()).Causesanerrororsystem
message if amount exceeds the amount of money in the guild bank or the
player’s allowed daily withdrawal amount.
Arguments:
amountAmount of money to withdraw (in copper) (number)
Chapter 27 API Reference 999
ZoomOut
Sets the world map to show the area containing its current area.
Only used by the default UI in certain circumstances: to ‘‘zoom out’’ from a
multi-level map (e.g. Dalaran or a dungeon) to the containing zone/continent.
May cause problems when not used in such cases.
Lua API abs
Returns the absolute value of a number.
absoluteValue = abs(x)
Alias for the standard library function math.abs.
Arguments:
x—A number (number)
Returns:
absoluteValueAbsolute value of x(number)
Lua API assert
Causes a Lua error if a condition is failed.
value = assert(condition, “message“)
Arguments:
conditionAny value (commonly the result of an expression) (value)
messageError message to be produced if condition is false or nil
(string)
Returns:
value—The condition value provided, if not false or nil (value)
Example:
assert(x < y)
-- causes a Lua error if the value of x is not less than the value
-- of y when called
assert(not UnitIsDead(“player“), “Oh noes!“))
-- causes a Lua error with text “Oh noes!“ if the player is dead
-- when called
Lua API ceil
Returns the smallest integer larger than or equal to a number.
ceiling = ceil(x)
Alias for the standard library function math.ceil.
Arguments:
x—A number (number)
Returns:
ceilingSmallest integer larger than or equal to x(number)
Lua API collectgarbage
Interface to the Lua garbage collector.
collectgarbage(option [, arg])
1000 Part IV Reference
Arguments:
optionOne of the following options
collectPerforms a full garbage collection cycle
countReturns the total Lua memory usage (in kilobytes)
restartRestarts the garbage collector
setpauseSetsthegarbagecollectorspausepercentagetoarg; e.g., if 200,
the collector waits for memory usage to double before starting a new cycle
setstepmulSets the garbage collector’s speed (as a percentage relative to
memory allocation) to arg; e.g., if 200, the collector runs twice as fast as mem-
ory is allocated
stepPerforms a garbage collection step, with size arg
stopStops the garbage collector
arg (optional)Argument applicable to some options
Lua API date
Returns a formatted date/time string for a date (or the current date).
dateValue = date([“format“ [, time]])
Alias to the standard library function os.date.
Arguments:
format (optional)A string describing the formatting of time values (as
in the ANSI C strftime()function), or *t to return the time as a table;
optionally preceded by !for Coordinated Universal Time instead of the
local time zone; omitted for a date printed in the default format (string)
time (optional)Time value to be formatted (see time() for description); if
omitted, uses the current time (number)
Returns:
dateValueA formatted date/time string, (string or table)
Examples:
-- Example #1
date()
-- returns (e.g.) “Sun Jun 14 01:31:41 2009“
-- Example #2
date(“*t“)
-- returns { hour=1, min=31, sec=41, wday=1, day=14, month=6,
-- year=2009, yday=165, isdst=true }
debuglocals
Returns information about the local variables at a given stack depth.
localsInfo = debuglocals(stackLevel)
Arguments:
stackLevelThe stack level to query (number)
Chapter 27 API Reference 1001
Returns:
localsInfoA string detailing the local variables at the given stack depth.
(string)
debugprofilestart
Starts/resets the high resolution profiling timer.
Subsequent calls to debugprofilestop() will return the current value of the
timer.
debugprofilestop
Returns the value of the profiling timer.
time = debugprofilestop()
Returns:
timeCurrent value of the profiling timer (in milliseconds, with
sub-millisecond precision) (number)
Example:
-- can be used to test the efficiency of a segment of code:
function myFunction()
debugprofilestart()
-- function body goes here
print(format(“myFunction executed in %f ms“, debugprofilestop()))
end
debugstack
Returns information about the current function call stack.
debugstring = debugstack(start, countTop, countBot)
Arguments:
startStack level at which to begin listing functions; 0 is the debugstack()
function itself, 1is the function that called debugstack(),2isthe
function that called function 1, etc. Defaults to 1if omitted (number)
countTopMaximum number of functions to output at the top of the stack
trace (number)
countBotMaximum number of functions to output at the bottom of the stack
trace (number)
Returns:
debugstringA multi-line string describing the current function call stack
(string)
Example:
print(debugstack())
-- output:
[string “print(debugstack())“]:1: in main chunk
[C]: in function 'RunScript'
Interface\FrameXML\ChatFrame.lua:1826: in function '?’
Interface\FrameXML\ChatFrame.lua:3332: in function i
1002 Part IV Reference
’ChatEdit_ParseText’
Interface\FrameXML\ChatFrame.lua:3052: in function 'ChatEdit_SendText’
Interface\FrameXML\ChatFrame.lua:3073: in function i
<Interface\FrameXML\ChatFrame.lua:3072>
[C]: in function 'ChatEdit_OnEnterPressed'
[string “*:OnEnterPressed“]:1: in function i
<[string “*:OnEnterPressed“]:1>
Lua API deg
Converts an angle measurement in radians to degrees.
degrees = deg(radians)
Alias for the standard library function math.deg.
Arguments:
radiansAn angle specified in radians (number)
Returns:
degreesThe angle specified in degrees (number)
Lua API difftime
Returns the number of seconds between two time values.
seconds = difftime(time2, time1)
Alias for the standard library function os.difftime.
Arguments:
time2—A time value (see time() for description) (number)
time1—A time value (see time() for description) (number)
Returns:
secondsNumber of seconds between time2 and time1;equiva-
lent to time2time1 on all current WoW clients (number)
Lua API error
Causes a Lua error message.
error(“message“ [, level])
Arguments:
messageAn error message to be displayed (string)
level (optional)Level in the function stack at which the error message
begins providing function information; e.g. 1(the default, if omitted) to start at
the position where error() was called, 2 to start at the function which called
error(), 3 to start at the function which called that function, etc. (number)
Lua API exp
Returns the value of the exponential function for a number.
exp = exp(x)
Alias for the standard library function math.exp.
Arguments:
x—A number (number)
Chapter 27 API Reference 1003
Returns:
expValue of the mathematical constant *e* (Euler’s number) raised to the xth
power (number)
Lua API floor
Returns the largest integer smaller than or equal to a number.
floor = floor(x)
Alias for the standard library function math.floor.
Arguments:
x—A number (number)
Returns:
floorLargestintegersmallerthanorequaltox(number)
forceinsecure
Causes the current execution path to continue outside the secure environment.
Meaningless when called from outside of the secure environment.
Lua API format
Returns a formatted string containing specified values.
formatted = format(“formatString“, ...)
Alias for the standard library function string.format. This version, however,
includes the positional argument specifiers from Lua 4.0.
Lua does not support the ANSI C format specifiers *,l,L,n,p,andhbut
includes an extra specifier, q, which formats a string in a form suitable to be
safely read back by the Lua interpreter; the string is written between double
quotes, and all double quotes, newlines, embedded zeros, and backslashes in
the string are correctly escaped when written.
Arguments:
formatStringA string containing format specifiers as per the ANSI C
printf function (string)
...A list of values to be included in the formatted string (list)
Returns:
formattedThe formatted string (number)
Example:
string.format(“%s %q“, “Hello“, “Azeroth!“) -- string and quoted string
-- returns 'Hello “Azeroth!“’
string.format(“%c%c%c“, 76,117,97) -- char
-- returns 'Lua’
string.format(“%e, %E“, math.pi,math.pi) -- exponent
-- returns '3.141593e+000, 3.141593E+000’
string.format(“%f, %g“, math.pi,math.pi) -- float and compact float
--returns '3.141593, 3.14159’
string.format(“%d, %i, %u“, -100,-100,-100) -- signed, signed, i
unsigned integer
-- returns '-100, -100, 4294967196’
string.format(“%o, %x, %X“, -100,-100,-100) -- octal, hex, hex
-- returns '37777777634, ffffff9c, FFFFFF9C’
1004 Part IV Reference
Lua API frexp
Returns the normalized fraction and base-2 exponent for a number.
m, e = frexp(x)
Alias for the standard library function math.frexp.
Arguments:
x—A number (number)
Returns:
mA number whose absolute value is in the range [0.5, 1), or 0 if xis 0 (number)
eAn integer, such that x = m * 2 &circ; e (number)
geterrorhandler
Returns the current error handler function.
handler = geterrorhandler()
Returns:
handlerThe current error handler (function)
Example:
local myError = “Something went horribly wrong!“
geterrorhandler()(myError)
Lua API getfenv
Returns the environment for a function (or the global environment).
env = getfenv([f]) or getfenv([stackLevel])
If the environment has a __environment metatable, that value is returned
instead.
Arguments:
f(optional)A function (function)
stackLevel (optional)Level of a function in the calling stack (number)
Returns:
envTable containing all variables in the function’s environment, or
the global environment if for stackLevel is omitted (table)
getglobal
Returns the value of a global variable.
value = getglobal(“name“)
Often used in the default UI in cases where several similar names are
systematically constructed. Examples:
In a script attached to a frame template, getglobal(self:GetName()..
“Icon“) can refer to the Texture whose name is defined in XML as
$parentIcon.
Chapter 27 API Reference 1005
Several sets of localized string tokens follow standard formats: e.g.
getglobal(“ITEM_QUALITY“..quality..“_DESC) returns the name for
the numeric quality.
Equivalent to _G.name or _G[“name“].
Arguments:
nameName of a global variable (string)
Returns:
valueValue of the given variable (value)
Lua API getmetatable
Returns an object’s metatable.
metatable = getmetatable(object)
Arguments:
objectAny table or userdata object (value)
Returns:
metatableContents of the object’s __metatable field, or nil if the object has
no metatable (value)
Lua API gmatch
Returns an iterator function for finding pattern matches in a string.
iterator = gmatch(“s“, “pattern“)
Alias for the standard library function string.gmatch.
Arguments:
s—A string (string)
patternA regular expression pattern (string, pattern)
Returns:
iteratorA function which, each time it is called, returns the next capture of
pattern in the string s; always returns the whole string if pattern specifies no
captures (function)
Example:
-- print the components of an item link
for w in gmatch(link, “([%d-]+)“) do
print(w)
end
-- example output, given an enchanted Heavy Lamellar
-- Gauntlets of the Gorilla:
-- 10242
-- 2564
-- 0
-- 0
-- 0
-- 0
-- 614
-- 0
1006 Part IV Reference
Lua API gsub
Returns a string in which occurrences of a pattern are replaced.
newString, numMatched = gsub(“s“, “pattern“, “rep“ [, maxReplaced]) or i
gsub(“s“, “pattern“, repTable [, maxReplaced]) or gsub(“s“, “pattern“, i
repFunc [, maxReplaced])
Alias for the standard library function string.gsub.
Arguments:
s—A string (string)
patternA regular expression pattern (string, pattern)
repString with which to replace occurrences of pattern;maycon-
tain specifiers for numbered captures in the pattern (string)
repTableTable containing replacement strings; replacements are looked up
using captured substrings as keys, or the entire match if pattern specifies no
captures (table)
repFuncFunction to supply replacement strings; called with captured
substrings (or the entire match if pattern specifies no captures) as arguments
(function)
maxReplaced (optional)Maximum number of replacements to be made
(number)
Returns:
newString—A copy of sin which occurrences of the pattern have been
replaced as specified (string)
numMatchedNumber of matches found (number)
Example:
gsub(“banana“, “a“, “A“, 2)
-- returns “bAnAna“, 2
gsub(“banana“, “(a)(n)“, “%2%1“)
-- returns “bnanaa“, 2
gsub(“banana“, “[an]“, {a=“o“,n=“m“})
-- returns “bomomo“, 5
gsub(“banana“, “(a)“, strupper)
-- returns “bAnAnA“, 3
hooksecurefunc
Add a function to be called after execution of a secure function.
hooksecurefunc([table,] “function“, hookfunc)
Allows one to ‘‘post-hook’’ a secure function without tainting the original.
The original function will still be called, but the function supplied will be called
after the original, with the same arguments. Return values from the supplied
function are discarded. Note that there is no API to remove a hook from a
function: any hooks applied will remain in place until the UI is reloaded.
Only allows hooking of functions named by a global variable; to hook a script
handler on a Frame object, see Frame:HookScript().
Chapter 27 API Reference 1007
Arguments:
table (optional)A table object that contains the function to be hooked (table)
functionThe name of the function to be hooked (string)
hookfuncThe function to be called each time the original function is called
(function)
Examples:
-- Example #1
-- Keep a counter of how many times your character has jumped,
-- and display in chat
local counter = 0
local function hook_JumpOrAscendStart(...)
counter = counter + 1
ChatFrame1:AddMessage(“Boing! Boing! - “ .. counter .. “ jumps.“)
end
hooksecurefunc(“JumpOrAscendStart“, hook_JumpOrAscendStart)
-- Example #2
-- Hook GameTooltip:SetAction() to display how many spell casts you can
-- make. It does this by scanning the second line of the tooltip, and
-- matching it against the pattern “(%d+) “ .. MANA, where MANA is the
-- global string for “Mana“ in the current locale.
local function hook_SetAction(self, ...)
-- The second line of the tooltip is
-- getglobal(self:GetName()..“TextLeft2“)
local line = getglobal(self:GetName() .. “TextLeft2“)
local text = line:GetText() or ““
local manaCost = text:match(“(%d+) “ .. MANA)
if manaCost then
-- Convert the mana cost to a number
manaCost = tostring(manaCost)
-- Get the player’s current mana, and calculate the numnber of casts
local mana = UnitMana(“player“)
local numCasts = math.floor(mana / manaCost)
-- Add the line to the tooltip, colored blue
self:AddLine(“You can cast this spell “ .. numCasts .. i
“ times“, 0.4, 0.4, 1.0)
-- Call this to ensure the tooltip is properly resized
self:Show()
end
end
hooksecurefunc(GameTooltip, “SetAction“, hook_SetAction)
Lua API ipairs
Returns an iterator function for integer keys in a table.
iterator, t, index = ipairs(t)
Return values are such that the construction
for k,v in ipairs(t) do
-- body
end
1008 Part IV Reference
will iterate over the pairs 1,t[1],2,t[2], etc, up to the first integer key
absent from the table.
Arguments:
t—A table (table)
Returns:
iteratorAn iterator (function)
tThe table provided (table)
indexAlways 0; used internally (number)
issecure
Returns whether the current execution path is secure.
secure = issecure()
Meaningless when called from outside of the secure environment: always
returns nil in such situations.
Returns:
secure1if the current execution path is secure; otherwise nil (1nil)
issecurevariable
Returns whether a variable is secure (and if not, which addon tainted it).
issecure, taint = issecurevariable([table,] “variable“)
Arguments:
table (optional)A table to be used when checking table elements (table)
variableThe name of a variable to check. In order to check the status of a
table element, you should specify the table, and then the key of the element
(string)
Returns:
issecure1if the variable is secure; otherwise nil (1nil)
taintName of the addon that tainted the variable, or nil if the variable is
secure (string)
Lua API ldexp
Returns the number generated by a normalized fraction and base-2 exponent.
x = ldexp(m, e)
Alias for the standard library function math.ldexp.
Arguments:
m—A number (number)
e—A number (number)
Returns:
x—The value of m*2 ˆe(number)
Lua API loadstring
Loads and compiles Lua source code.
chunk, error = loadstring(“s“ [, “chunkname“])
Chapter 27 API Reference 1009
Arguments:
sA string containing Lua code (string)
chunkname (optional)Name for the loaded chunk; used in error messages and
debug information (string)
Returns:
chunkA function which can be run to execute the provided code, or nil if the
code could not be compiled (function)
errorError message, if the code could not be compiled (string)
Lua API log
Returns the natural logarithm of a number.
naturalLog = log(x)
Alias for the standard library function math.log.
Arguments:
x—A number (number)
Returns:
naturalLogThe natural logarithm of x(number)
Lua API log10
Returns the base-10 logarithm of a number.
base10log = log10(x)
Alias for the standard library function math.log10.
Arguments:
x—A number (number)
Returns:
base10logThe base-10 logarithm of x(number)
Lua API max
Returns the greatest of a list of numbers.
maximum = max(...)
Alias for the standard library function math.max.
Arguments:
...A list of numbers (list)
Returns:
maximumThe highest number among all arguments (number)
Lua API min
Returns the least of a list of numbers.
maximum = min(...)
Alias for the standard library function math.min.
Arguments:
...A list of numbers (list)
1010 Part IV Reference
Returns:
maximumThe lowest number among all arguments (number)
Lua API mod
Returns the remainder from division of two numbers.
remainder = mod(x, y)
Alias for the standard library function math.fmod.
Arguments:
x—A number (number)
y—A number (number)
Returns:
remainderRemainder of the division of xby ythat rounds the quotient
towards zero (number)
Lua API newproxy
Creates a zero-length userdata with an optional metatable.
userdata = newproxy(boolean) or newproxy(userdata)
newproxy is an experimental, undocumented and unsupported function in the
Lua base library. It can be used to create a zero-length userdata, with a optional
proxy.
This function allows you to bypass the table type restriction on setmetatable,
and thus create just a metatable. One of the main benefits from doing this is
that you don’t have to take the full overhead of creating a dummy table, and
it’s the only object that honors the metamethod __len.
Arguments:
booleanControls if the returned userdata should have a metatable or not.
(boolean)
userdataNeeds to be a proxy. The metatable will be shared between the
proxies. (userdata)
Returns:
userdataA zero-length user-data object. (userdata)
Example:
proxy = newproxy(true)
getmetatable(proxy).__len = function() return 3 end
print(#proxy) -- prints 3
Lua API next
Returns the next key/value pair in a table.
nextKey, nextValue = next(t [, key])
Arguments:
t—A table (table)
key (optional)A key in the table (value)
Chapter 27 API Reference 1011
Returns:
nextKeyThe next key in the table t(value)
nextValueValue associated with the next key in the table t(value)
Lua API pairs
Returns an iterator function for a table.
iterator, t, index = pairs(t)
Return values are such that the construction
for k,v in pairs(t)
-- body
end
will iterate over all key/value pairs in the table.
Arguments:
t—A table (table)
Returns:
iterator—The next() function (function)
tThe table provided (table)
index—Always nil; used internally (number)
Lua API pcall
Executes a function in protected mode.
status, ... = pcall(f, ...)
When running a function in protected mode, any errors do not propagate
beyond the function (i.e. they do not stop all execution and call the default
error handler).
Arguments:
f—A function (function)
...Arguments to be passed to the function (list)
Returns:
statusTrue if the function succeeded without errors; false otherwise
(boolean)
...—If status is false, the error message produced by the function; if
status is true, the return values from the function (list or string)
Lua API rad
Converts an angle specified in degrees to radians.
radians = rad(degrees)
Alias for the standard library function math.rad.
Arguments:
degreesAn angle specified in degrees (number)
Returns:
radiansThe angle specified in radians (number)
1012 Part IV Reference
Lua API random
Generates a pseudo-random number.
randomNum = random([m [, n]])
Alias for the standard library function math.random.
Arguments:
m(optional)First limit for randomly generated numbers (number)
n(optional)Second limit for randomly generated numbers (number)
Returns:
randomNumIf called without arguments, a uniform pseudo-random real num-
ber in the range [0,1); if mis specified, a uniform pseudo-random integer in the
range [1,m]; if both mand nare specified, a uniform pseudo-random integer in
the range [m,n] (number)
Lua API rawequal
Returns whether two values are equal without invoking any metamethods.
isEqual = rawequal(v1, v2)
Arguments:
v1—Any value (value)
v2—Any value (function)
Returns:
isEqualTrue if the values are equal; false otherwise (boolean)
Lua API rawget
Returns the real value associated with a key in a table without invoking any
metamethods.
value = rawget(t, key)
Arguments:
t—A table (table)
key—A key in the table (value)
Returns:
value—Value of t[key] (value)
Lua API rawset
Sets the value associated with a key in a table without invoking any
metamethods.
rawset(t, key, value)
Arguments:
t—A table (table)
keyA key in the table (cannot be nil)(value)
valueNew value to set for the key (value)
scrub
Replaces non-simple values in a list with nil.
... = scrub(...)
Chapter 27 API Reference 1013
All simple values (strings, numbers, and booleans) are passed from the input
list to the output list unchanged. Non-simple values (tables, functions, threads,
and userdata) are replaced by nil in the output list.
Arguments:
...A list of values (list)
Returns:
...The list of input values, with all non-simple values replaced by nil (list)
Example:
scrub(“a“, print, 1, {1,2,3}, math.pi)
-- returns “a“, nil, 1, nil, 3.1415926535898
securecall
Calls a function without tainting the execution path.
... = securecall(function, ...)
Meaningless when called from outside of the secure environment.
Used in Blizzard code to call functions which may be tainted or operate on
potentially tainted variables. For example, consider the function Close
SpecialWindows, which iterates through the table UISpecialFrames and
hides any frames named therein. Addon authors may put the names of their
frames in that table to make them automatically close when the user presses
the ESC key, but this taints UISpecialFrames. Were the default UI to then call
CloseSpecialWindows normally, every frame in UISpecialFrames would
become tainted, which could later lead to errors when handlers on those
frames call protected functions.
Instead, the default UI uses securecall(CloseSpecialWindows):within
CloseSpecialWindows the execution path may become tainted, but afterward
the environment remains secure.
Arguments:
functionFunction to be called (function)
...Arguments to the function (list)
Returns:
...Values returned after calling the function (list)
Lua API select
Returns one or more values from a list (...), or the number of values in a list.
... = select(index, ...) or select(“#“, ...)
Arguments:
indexIndex of a value in the list (number)
#The string “#“ (string)
...A list of values (list)
Returns:
...If called with a first argument of “#“, the number of values in the list;
otherwise, all values in the list starting with the value at position index (list)
1014 Part IV Reference
seterrorhandler
Changes the error handler to a specified function.
seterrorhandler(errHandler)
The error handler is called by Lua’s error() function, which in turn is called
whenever a Lua error occurs. WoW’s default error handler displays the error
message, a stack trace and information about the local variables for the
function. This dialog will only be shown if the ‘‘Show Lua errors’’ option is
enabled in Interface Options.
Arguments:
errHandlerA function to use as the error handler (function)
Lua API setfenv
Sets the environment to be used by a function.
f = setfenv([f,] t) or setfenv([stackLevel,] t)
If the environment has a __environment metatable, this function will error.
Arguments:
f(optional)A function (function)
stackLevel (optional)Level of a function in the calling stack, or 0 to set the
global environment (number)
t—A table (table)
Returns:
fThe input function f(function)
setglobal
Sets a global variable to a specified value.
setglobal(“name“, value)
Allows setting the value of a global variable in contexts where its name might
be overridden by that of a local variable; i.e. setglobal(name, value) is
equivalent to _G.name = value or _G[“name“] = value.
Arguments:
nameName of a global variable (string)
valueNewvalueforthevariable(value)
Lua API setmetatable
Sets the metatable for a table.
t = setmetatable(t, metatable)
Arguments:
t—A table (table)
metatableA metatable for the table t,ornil to remove an existing metatable
(table)
Returns:
tThe input table t(table)
Chapter 27 API Reference 1015
Lua API sort
Sorts a table.
sort(table [, comparator])
Alias for the standard library function table.sort.
Arguments:
table—A table (number)
comparator (optional)A function to compare table elements during
the sort; takes two arguments and returns true if the first argument
should be ordered before the second in the sorted table; equivalent
to function(a,b) return a < b end if omitted (function)
Examples:
-- Example #1
aTable = {“a“, “c“, “g“, “e“, “b“, “f“, “d“}
sort(aTable)
print(aTable)
-- shows “a b c d e f g“
sort(aTable, function(a,b) return a>b end)
print(aTable)
-- shows “g f e d c b a“
-- Example #2
complexTable = {
{
name = “Gorrok“,
level = 80,
class = “WARRIOR“,
}
{
name = “Spin“,
level = 79,
class = “SHAMAN“,
},
{
name = “Valiant“,
level = 80,
class = “HUNTER“,
}
}
sort(complexTable, function(a,b) return a.name < b.name end)
for _, info in ipairs(complexTable) do print(info.name) end
-- prints “Gorrok, Spin, Valiant“
sort(complexTable, function(a,b) return a.level < b.level end)
for _, info in ipairs(complexTable) do print(info.name) end
-- prints “Spin, Gorrok, Valiant“ (or “Spin, Valiant, Gorrok“; order
-- of equal elements is not defined)
sort(complexTable, function(a,b) return a.class < b.class end)
for _, info in ipairs(complexTable) do print(info.name) end
-- prints “Valiant, Spin, Gorrok“
1016 Part IV Reference
Lua API sqrt
Returns the square root of a number.
root = sqrt(x)
Alias for the standard library function math.sqrt.
Arguments:
x—A number (number)
Returns:
rootThe square root of x(number)
Lua API strbyte
Returns the numeric code for one or more characters in a string.
value, ... = strbyte(“s“ [, firstChar [, lastChar]])
Alias for the standard library function string.byte.
Arguments:
s—A string (string)
firstChar (optional)Position of a character in the string (can be negative to
count backwards from the end of the string); defaults to 1if omitted (number)
lastChar (optional)Position of a later character in the string (can be negative
to count backwards from the end of the string); defaults to firstChar if omitted
(number)
Returns:
valueNumeric code for the character at position firstChar in the string
(number)
...A list of numbers, each the numeric codes of additional characters in the
string if lastChar specifies a position later in the string than firstChar (list)
Lua API strchar
Returns the character(s) for one or more numeric codes.
s = strchar(n [, ...])
Alias for the standard library function string.char.
Arguments:
nAn integer (number)
... (optional)Additional integers (number)
Returns:
sA string containing the character(s) for the given numeric code(s) (number)
strconcat
Joins a list of strings (with no separator).
result = strconcat(“...“)
Equivalent to strjoin(““, ...). If no strings are provided, returns the
empty string (““).
Arguments:
...A list of strings to concatenate (string)
Chapter 27 API Reference 1017
Returns:
resultThe concatenated string (string)
Lua API strfind
Returns information about matches for a pattern in a string.
start, end, ... = strfind(“s“, “pattern“ [, init [, plain]])
Alias for the standard library function string.find.
Returns nil if no matches are found.
Arguments:
s—A string (string)
patternA regular expression pattern (string, pattern)
init (optional)Initial position in the string sat which to begin the search;
defaults to 1if omitted (number)
plain (optional)True to perform a simple substring search (i.e. considering
pattern only as a literal string, not a regular expression); false or omitted oth-
erwise (boolean)
Returns:
start—Character position in sat which the first match begins (number)
end—Character position in sat which the first match ends (number)
...Captured substrings from s,ifpattern specifies captures (list)
Example:
strfind(“Welcome to Azeroth!“, “Azeroth“)
-- returns 12, 18
strfind(“|cffffff00|Hquest:982:17|h[Deep Ocean, Vast Sea]|h|r“, i
“quest:(%d+):([-%d]+)|h%[(.-)%]“)
-- returns 11, 48, “982“, “17“, “Deep Ocean, Vast Sea“
strjoin
Joins a list of strings together with a given separator.
text = strjoin(“sep“, ...)
If given a list of strings not already in a table, this function can be used instead
of table.concat forbetterperformance.
Also available as string.join (though not provided by the Lua standard
library).
Arguments:
sepA separator to insert between joined strings (string)
...A list of strings to be joined together (list)
Returns:
textThe list of strings joined together with the given separator string
(string)
Example:
strjoin(“,“, “alice“, “bob“, “carol“)
-- Returns “alice,bob,carol“
1018 Part IV Reference
strjoin(“ mississippi, “, “one“, “two“, “three“)
-- Returns “one mississippi, two mississippi, three
Lua API strlen
Returns the number of characters in a string.
length = strlen(“s“)
Alias for the standard library function string.len.
Arguments:
s—A string (string)
Returns:
lengthNumber of characters in the string (number)
strlenutf8
Returns the length of a string, taking UTF-8 multi-byte characters into account.
length = strlenutf8(“string“)
Arguments:
stringThe string to query. (string)
Returns:
lengthThe length of the given string, taking UTF-8 multi-byte characters into
account. (number)
Lua API strlower
Returns a copy of a string with all uppercase letters converted to lowercase.
lowerCase = strlower(“s“)
Alias for the standard library function string.lower
Arguments:
s—A string (string)
Returns:
lowerCaseA copy of the string swith all uppercase letters converted to low-
ercase (string)
Lua API strmatch
Returns the matches for a for a pattern in a string.
match, ... = strmatch(“s“, “pattern“)
Alias for the standard library function string.match.
Arguments:
s—A string (string)
patternA regular expression pattern (string, pattern)
Returns:
matchFirst substring of smatching pattern,orthefirstcapture
if pattern specifies captures; nil if no match is found (string)
...Additional captures found, if pattern specifies multiple captures (list)
Chapter 27 API Reference 1019
Example:
strmatch(“Your share of the loot is 97 Copper.“, “%d+ %a+“)
-- returns “97 Copper“
strmatch(“Your share of the loot is 97 Copper.“, “(%d+) (%a+)“)
-- returns “97“, “Copper“
Lua API strrep
Returns a string produced by a number of repetitions of another string.
repeated = strrep(“s“, n)
Alias for the standard library function string.rep.
Arguments:
s—A string (string)
n—A number (number)
Returns:
repeatedThe concatenation of ncopies of the string s(string)
Example:
strrep(“spam “,8)
-- returns “spam spam spam spam spam spam spam spam “
strreplace
Fast simple substring substitution.
newText, count = strreplace(“text“, “pattern“, “replacement“, “count“)
Matches the semantics of string.gsub, but only finds and replaces specific
substrings rather than using more powerful and more computationally
expensive regular expression matching. Thus, this function can be used in
place of string.gsub in performance-critical situations where only simple
matching is needed.
Also available as string.replace (though not provided by the Lua standard
library).
Arguments:
textText to be altered (string)
patternA substring to be located within the source text (string)
replacementText to be inserted in place of the found pattern (string)
countMaximum number of replacements to be made (string)
Returns:
newTextThe input string with matching substrings replaced (string)
countNumber of occurrences of the substring replaced (number)
Lua API strrev
Returns the reverse of a string.
s = strrev(“s“)
Alias for the standard library function string.reverse.
1020 Part IV Reference
Arguments:
s—A string (string)
Returns:
sA string containing the characters of string sin reverse order (string)
Example:
strrev(“abcdef“)
-- returns “fedcba“
strrev(“nametag“)
-- returns “gateman“
strrev(“Step on no pets“)
-- returns “step on no petS“
strsplit
Splits a string based on another seperator string.
... = strsplit(“sep“, “text“, limit)
Also available as string.split (though not provided by the Lua standard
library).
Arguments:
sepThe seperator string to use (string)
textThe text to split (string)
limitThe maximum number of pieces to split the string into (number)
Returns:
...A list of strings, split from the input text based on the seperator string
(string)
Example:
-- Split the string “a:b:c:d“
strsplit(“:“, “a:b:c:d“, 2)
-- Returns “a“, “b:c:d“
-- Split the string “a::b::c::d“
strsplit(“::“, “a::b::c::d“)
-- Returns “a“, “b“, “c“, “d“
Lua API strsub
Returns a substring of a string.
s = strsub(“s“, firstChar [, lastChar])
Alias for the standard library function string.sub.
Arguments:
s—A string (string)
firstCharPosition of a character in the string (can be nega-
tive to count backwards from the end of the string) (number)
lastChar (optional)Position of a later character in the string (can be negative
to count backwards from the end of the string); defaults to -1if omitted (number)
Chapter 27 API Reference 1021
Returns:
s—The substring of sstarting at the character firstChar and ending with the
character lastChar (string)
strtrim
Trims leading and trailing characters (whitespace by default) from a string.
text = strtrim(“str“ [, “trimChars“])
Also available as string.trim (though not provided by the Lua standard
library).
Arguments:
strA string to trim (string)
trimChars (optional)A string listing the characters to be trimmed (e.g.
“[]{}()“ to trim leading and trailing brackets, braces, and parentheses); if
nil or omitted, whitespace characters (space, tab, newline, etc) are trimmed
(string)
Returns:
textThe trimmed string (string)
Examples:
-- Example #1
strtrim(“ This is a test “)
-- Returns “This is a test“
-- Example #2
strtrim(“121abc456“, “615“)
-- Returns “21abc4“
Lua API strupper
Returns a copy of a string with all lowercase letters converted to uppercase.
lowerCase = strupper(“s“)
Alias for the standard library function string.upper.
Arguments:
s—A string (string)
Returns:
lowerCaseA copy of the string swith all lowercase letters converted to
uppercase (string)
Lua API time
Returns the numeric time value for a described date/time (or the current time).
t = time([timeDesc])
Alias for the standard library function os.time.
According to the Lua manual, the returned value may vary across different
systems; however, the Lua libraries included with current WoW clients on both
Mac and Windows share the same implementation.
1022 Part IV Reference
For higher-precision time measurements not convertible to a date, see
GetTime().
Arguments:
timeDesc (optional)Table describing a date and time, as returned by
date(“*t“); if omitted, uses the current time (table)
Returns:
tNumber of seconds elapsed since midnight, January 1, 1970 UTC (number)
Lua API tinsert
Inserts a value into a table.
tinsert(table [, position] value)
Alias for the standard library function table.insert.
Arguments:
table—A table (table)
position (optional)Index in the table at which to insert the new value; if
omitted, defaults to #table + 1 (number)
value—Any value (value)
Lua API tonumber
Returns the numeric value of a string.
numValue = tonumber(x [, base])
Arguments:
xA string or number (value)
base (optional)Base in which to interpret the numeral (integer
between 2 and 36); letters ‘A-Z’ can be used to denote place values 10
or above in bases greater than 10; defaults to 10 if omitted (number)
Returns:
numValueNumeric value of xin the given base, or nil if the value cannot be
converted to a number (number)
Lua API tostring
Returns a string representation of a value.
stringValue = tostring(value)
Arguments:
value—Any value (value)
Returns:
stringValueString representation of the given value (if value is an object
with a __tostring metamethod, that method is used to produce the string rep-
resentation) (string)
Lua API tremove
Removes an element from a table.
tremove(table [, position])
Chapter 27 API Reference 1023
Alias for the standard library function table.remove.
Arguments:
table—A table (table)
position (optional)Index in the table from which to remove the value; if
omitted, defaults to #table (number)
Lua API type
Returns a string describing the data type of a value.
typeString = type(v)
Arguments:
v—Any value (value)
Returns:
typeStringA string describing the type of value v(string)
booleanA boolean value (true or false)
function—A function
nilThe special value nil
number—A numeric value
string—A string
table—A table
thread—A coroutine thread
userdataData external to the Lua environment (e.g. the main element of a
Frame object)
Lua API unpack
Returns the list of elements in a table.
... = unpack(t [, i [, j]])
Equivalent to
return t[i], t[i+1], ... t[j]
for an arbitrary number of elements.
Arguments:
t—A table (table)
i(optional)A numeric index to the table; defaults to 1if omitted (number)
j(optional)A numeric index to the table; defaults to #t if omitted (number)
Returns:
...The list of values in the table between indices iand j(list)
wipe
Removes all entries from a table.
emptyTable = wipe(aTable)
Arguments:
aTableA table whose contents are to be erased (table)
1024 Part IV Reference
Returns:
emptyTableThe input table, with all entries removed (table)
Lua API xpcall
Executes a function in protected mode with a custom error handler.
status, ... = xpcall(f, err)
Arguments:
f—A function (function)
errError handler function to be used should fcause an error (function)
Returns:
statusTrue if the function succeeded without errors; false otherwise
(boolean)
...—If status is false, the error message produced by the function; if
status is true, the return values from the function (list or string)
CHAPTER
28
API Categories
Finding the right function to accomplish a specific task in World of Warcraft
can be difficult, because there are over a thousand API functions that could be
used. This chapter provides a categorized listing of these functions to make
it easier to determine which the correct function is. Some functions appear in
more than one category, when necessary.
Achievement Functions
AddTrackedAchievementAdds an achievement to the objectives tracker UI
CanShowAchievementUIReturns whether the achievements UI should be
enabled
ClearAchievementComparisonUnitDisables comparing achievements/sta-
tistics with another player
GetAchievementCategoryReturns the numeric ID of the category to which
an achievement belongs
GetAchievementComparisonInfoReturns information about the compari-
son unit’s achievements
GetAchievementCriteriaInfoGets information about criteria for an achi-
evement or data for a statistic
GetAchievementInfoGets information about an achievement or statistic
GetAchievementInfoFromCriteriaGets information about an achievement
or statistic given a criterion ID
1025
1026 Part IV Reference
GetAchievementLinkReturns a hyperlink representing the player’s
progress on an achievement
GetAchievementNumCriteriaReturns the number of measured criteria for
an achievement
GetAchievementNumRewardsReturns the number of point rewards for an
achievement (currently always 1)
GetAchievementRewardReturns the number of achievement points
awarded for earning an achievement
GetCategoryInfoReturns information about an achievement/statistic cat-
egory
GetCategoryListReturns a list of all achievement categories
GetCategoryNumAchievementsReturns the number of achievements/sta-
tistics to display in a category
GetComparisonAchievementPointsReturns the comparison unit’s total
achievement points earned
GetComparisonCategoryNumAchievementsReturns the number of achieve-
ments completed by the comparison unit within a category
GetComparisonStatisticReturns the comparison unit’s data for a statistic
GetLatestCompletedAchievementsReturns a list of the player’s most re-
cently earned achievements
GetLatestCompletedComparisonAchievementsReturns a list of the com-
parison unit’s most recently earned achievements
GetNextAchievementReturns the next achievement for an achievement
which is part of a series
GetNumComparisonCompletedAchievementsReturns the number of achieve-
ments earned by the comparison unit
GetNumCompletedAchievementsReturns the number of achievements
earned by the player
GetNumTrackedAchievementsReturns the number of achievements flagged
for display in the objectives tracker UI
GetPreviousAchievementReturns the previous achievement for an
achievement which is part of a series
GetStatisticReturns data for a statistic
GetStatisticsCategoryListReturns a list of all statistic categories
GetTotalAchievementPointsReturns the player’s total achievement points
earned
Chapter 28 API Categories 1027
GetTrackedAchievementsReturns numeric IDs of the achievements flagged
for display in the objectives tracker UI
IsTrackedAchievementReturns whether an achievement is flagged for
display in the objectives tracker UI
RemoveTrackedAchievementRemoves an achievement from the objectives
tracker UI
SetAchievementComparisonUnitEnables comparing achievements/sta-
tistics with another player
Action Functions
ActionHasRangeReturns whether an action has a range restriction
CastPetActionCasts a pet action on a specific target
GetActionCooldownReturns cooldown information about an action
GetActionCountReturns the number of uses remaining for the given action
slot
GetActionInfoReturns information about an action slot
GetActionTextReturns the text label associated with an action
GetActionTextureReturns the icon texture for an action
GetPetActionCooldownReturns cooldown information about a given pet
action slot
GetPetActionInfoReturns information about a pet action
GetPetActionSlotUsableReturns whether a pet action can be used
GetPetActionsUsableReturns whether the pet’s actions are usable
HasActionReturns whether an action slot contains an action
IsActionInRangeReturns whether the player’s target is in range of an
action
IsAttackActionReturns whether an action is the standard melee Attack
action
IsAutoRepeatActionReturns whether an action is an automatically repeat-
ing action
IsConsumableActionReturns whether using an action consumes an item
IsCurrentActionReturns whether an action is currently being used
IsEquippedActionReturns whether an action contains an equipped item
IsStackableActionReturns whether an action uses stackable items
1028 Part IV Reference
IsUsableActionReturns whether an action is usable
PickupActionPuts the contents of an action bar slot onto the cursor or the
cursor contents into an action bar slot
PickupPetActionPuts the contents of a pet action slot onto the cursor or
the cursor contents into a pet action slot
PlaceActionPuts the contents of the cursor into an action bar slot
TogglePetAutocastTurns autocast on or off for a pet action
UseActionUses an action
ActionBar Functions
ChangeActionBarPageChanges the current action bar page
GetActionBarPageReturns the current action bar page
GetActionBarTogglesReturns the current visibility settings for the four
secondary action bars
GetBonusBarOffsetReturns the current ‘‘stance’’ offset for use with the
bonus action bar
GetPossessInfoReturns information about special actions available while
the player possesses another unit
IsPossessBarVisibleReturns whether a special action bar should be
shown while the player possesses another unit
SetActionBarTogglesConfigures display of additional ActionBars in the
default UI
Addon-related Functions
DisableAddOnMarks an addon as disabled
DisableAllAddOnsMarks all addons as disabled
EnableAddOnMarksanaddonasenabled
EnableAllAddOnsMarks all addons as enabled
GetAddOnDependenciesReturns a list of addons a given addon is dependent
upon
GetAddOnInfoReturns information about an addon
GetAddOnMetadataReturns the value of certain fields in an addon’s TOC
file
GetNumAddOnsReturns the number of addons in the addon listing
Chapter 28 API Categories 1029
InterfaceOptionsFrame_OpenToCategoryOpens the Interface Options
window and displays a given panel within it
InterfaceOptions_AddCategoryRegisters a panel to be displayed in the
Interface Options window
IsAddOnLoadOnDemandReturns whether an addon can be loaded without
restarting the UI
IsAddOnLoadedReturns whether an addon is currently loaded
LoadAddOnLoads a LoadOnDemand-capable addon
ResetDisabledAddOnsReverts changes to the enabled/disabled state of
addons
SendAddonMessageSends a chat-like message receivable by other addons
Arena Functions
AcceptArenaTeamAcceptsaninvitationtojoinanarenateam
ArenaTeamDisbandDisbands an arena team
ArenaTeamInviteByNameInvites a character to one of the player’s arena
teams
ArenaTeamLeaveLeaves an arena team
ArenaTeamRosterRequests arena team roster information from the server
ArenaTeamSetLeaderByNamePromotes an arena team member to team
captain
ArenaTeamUninviteByNameRemoves a member from an arena team
ArenaTeam_GetTeamSizeIDConverts an arena team size to the appropriate
numeric arena team identifier
CloseArenaTeamRosterEnds interaction with the Arena Team Roster
DeclineArenaTeamDeclines an arena team invitation
GetArenaCurrencyReturns the player’s amount of arena points
GetArenaTeamReturns information about one of the player’s arena teams
GetArenaTeamRosterInfoReturns information about an arena team mem-
ber
GetArenaTeamRosterSelectionReturns the currently selected member in
an arena team roster
GetCurrentArenaSeasonReturns a number identifying the current arena
season
1030 Part IV Reference
GetMaxArenaCurrencyReturns the maximum amount of arena points the
player can accrue
GetNumArenaOpponentsReturns the number of enemy players in an arena
match
GetNumArenaTeamMembersReturns the number of members in an arena team
GetPreviousArenaSeasonReturns a number identifying the previous arena
season
IsActiveBattlefieldArenaReturns whether the player is currently in an
arena match
IsArenaTeamCaptainReturns whether the player is the captain of an arena
team
IsBattlefieldArenaReturns whether the player is interacting with an
entity that allows queueing for arena matches
IsInArenaTeamReturns whether the player is on an arena team
SetArenaTeamRosterSelectionSelects a member in an arena team roster
SortArenaTeamRosterSorts the selected arena team’s roster
TurnInArenaPetitionTurns in a petition creating an arena team
Auction Functions
CalculateAuctionDepositReturns the deposit amount for the item cur-
rently being set up for auction
CanCancelAuctionReturns whether one of the player’s auctions can be
canceled
CanSendAuctionQueryReturns whether the player can perform an auction
house query
CancelAuctionCancels an auction created by the player
ClickAuctionSellItemButtonPicksupanitemfromorputsaniteminto
the ‘‘Create Auction’’ slot
CloseAuctionHouseEnds interaction with the Auction House UI
GetAuctionInvTypesReturns a list of the inventory subtypes for a given
auction house item subclass
GetAuctionItemClassesReturns a list of localized item class (category)
names
GetAuctionItemInfoReturns information about an auction listing
GetAuctionItemLinkReturns a hyperlink for an item in an auction listing
Chapter 28 API Categories 1031
GetAuctionItemSubClassesReturns a list of localized subclass names for a
given item class
GetAuctionItemTimeLeftReturns the time remaining before an auction
listing expires
GetAuctionSellItemInfoReturns information about the item currently
being set up for auction
GetAuctionSortReturns the current sort settings for auction data
GetBidderAuctionItemsRequests data from the server for the list of auc-
tions bid on by the player
GetInboxInvoiceInfoReturns auction house invoice information for a mail
message
GetNumAuctionItemsReturns the number of auction items in a listing
GetOwnerAuctionItemsRequests data from the server for the list of auctions
created by the player
GetSelectedAuctionItemReturns the index of the currently selected item
in an auction listing
PlaceAuctionBidPlaces a bid on (or buys out) an auction item
QueryAuctionItemsRequests data from the server for the list of auctions
meeting given search criteria
SetSelectedAuctionItemSelects an item in an auction listing
SortAuctionApplySortApplies a set of auction listing sort criteria set via
SortAuctionSetSort
SortAuctionClearSortClears any current sorting rules for an auction
house listing
SortAuctionSetSortBuilds a list of sort criteria for auction listings
StartAuctionCreates an auction for the item currently in the ‘‘auction
item’’ slot
Bank Functions
BankButtonIDToInvSlotIDReturns the inventoryID corresponding to a
bank item or bag slot
CloseBankFrameEnds interaction with the bank
EquipmentManager_UnpackLocationUnpacks an inventory location bitfield
into usable components
GetBankSlotCostReturns the cost of the next purchasable bank bag slot
1032 Part IV Reference
GetNumBankSlotsReturns information about purchased bank bag slots
PurchaseSlotPurchases the next available bank slot
Barbershop Functions
ApplyBarberShopStylePurchases the selected barber shop style changes
BarberShopResetResets barber shop options to the currently worn styles
CanAlterSkinLets you check if the player can change their skin color
CancelBarberShopExits a barber shop session
GetBarberShopStyleInfoReturns information about the selected barber
shop style option
GetBarberShopTotalCostReturns the total price of selected barber shop
style changes
GetFacialHairCustomizationReturns a token used for displaying facial
feature customization options
GetHairCustomizationReturns a token used for displaying ‘‘hair’’ cus-
tomization options
SetNextBarberShopStyleSelects the next style for a barber shop style
option
Battlefield Functions
AcceptAreaSpiritHealAccepts the next upcoming periodic resurrection
from a battleground spirit healer
AcceptBattlefieldPortAccepts the offered teleport to a battleground/
arena or leaves the battleground/arena or queue
CanJoinBattlefieldAsGroupReturns whether the battleground for which
the player is queueing supports joining as a group
CancelAreaSpiritHealDeclines the next upcoming periodic resurrection
from a battleground spirit healer
CloseBattlefieldEnds interaction with the battleground queueing UI
GetAreaSpiritHealerTimeReturns the time remaining until a nearby bat-
tleground spirit healer resurrects all players in its area
GetBattlefieldEstimatedWaitTimeReturns the estimated wait time on a
battleground or arena queue
Chapter 28 API Categories 1033
GetBattlefieldFlagPositionReturns the position of a flag in a battle-
ground
GetBattlefieldInfoReturns information about a battleground for which
the player can queue
GetBattlefieldInstanceExpirationReturns the amount of time remain-
ing before all players are removed from the instance, if in a battleground
instance where the match has completed
GetBattlefieldInstanceInfoReturns a numeric ID for a battleground
instance in the battleground queueing list
GetBattlefieldInstanceRunTimeReturns the amount of time since the
current battleground instance opened
GetBattlefieldMapIconScaleReturns the scale to be used for displaying
battleground map icons
GetBattlefieldPortExpirationReturns the time left on a battleground or
arena invitation
GetBattlefieldPositionReturns the position of a battleground team
member not in the player’s group
GetBattlefieldScoreReturns basic scoreboard information for a battle-
ground/arena participant
GetBattlefieldStatDataReturns battleground-specific scoreboard infor-
mation for a battleground participant
GetBattlefieldStatInfoReturns information about a battleground-spe-
cific scoreboard column
GetBattlefieldStatusReturns information about an active or queued
battleground/arena instance
GetBattlefieldTeamInfoReturns info about teams and their ratings in a
rated arena match
GetBattlefieldTimeWaitedReturns the amount of time elapsed since the
player joined the queue for a battleground/arena
GetBattlefieldVehicleInfoReturns information about special vehicles in
the current zone
GetBattlefieldWinnerReturns the winner of the current battleground or
arena match
GetBattlegroundInfoReturns information about available battlegrounds
GetNumBattlefieldFlagPositionsReturns the number of battleground
flags for which map position information is available
1034 Part IV Reference
GetNumBattlefieldPositionsReturns the number of team members in the
battleground not in the player’s group
GetNumBattlefieldScoresReturns the number of participant scores avail-
able in the current battleground
GetNumBattlefieldStatsReturns the number of battleground-specific
statistics on the current battleground’s scoreboard
GetNumBattlefieldVehiclesReturns the number of special vehicles in the
current zone
GetNumBattlefieldsReturns the number of instances available for a bat-
tleground
GetNumBattlegroundTypesReturns the number of different battlegrounds
available
GetRealNumPartyMembersReturns the number of members in the player’s
non-battleground party
GetRealNumRaidMembersReturns the number of members in the player’s
non-battleground raid
GetSelectedBattlefieldReturns the index of the selected battleground
instance in the queueing list
IsActiveBattlefieldArenaReturns whether the player is currently in an
arena match
IsBattlefieldArenaReturns whether the player is interacting with an
entity that allows queueing for arena matches
IsRealPartyLeaderReturns whether the player is the leader of a non-
battleground party
IsRealRaidLeaderReturns whether the player is the leader of a non-
battleground raid
JoinBattlefieldJoins the queue for a battleground instance
LeaveBattlefieldImmediately exits the current battleground instance
PlayerIsPVPInactiveReturns whether a battleground participant is inac-
tive (and eligible for reporting as AFK)
ReportPlayerIsPVPAFKReports a battleground participant as AFK
RequestBattlefieldPositionsRequests information from the server
about team member positions in the current battleground
RequestBattlefieldScoreDataRequests battlefield score data from the
server
RequestBattlegroundInstanceInfoRequests information about available
instances of a battleground from the server
Chapter 28 API Categories 1035
SetBattlefieldScoreFactionFilters the battleground scoreboard by fac-
tion/team
SetSelectedBattlefieldSelects a battleground instance in the queueing
list
ShowBattlefieldListRequests to change instances for a battleground to
which the player is already queued
ShowMiniWorldMapArrowFrameShows or hides the battlefield minimap’s
player arrow
SortBattlefieldScoreDataSorts the battleground scoreboard
UnitInBattlegroundReturns whether a unit is in same battleground
instance as the player
Blizzard Internal Functions
DetectWowMouseDetects the presence of a ‘‘WoW’’ compatible multi-button
mouse
newproxyCreates a zero-length userdata with an optional metatable
Buff Functions
CancelItemTempEnchantmentCancels a temporary weapon enchant
CancelShapeshiftFormCancels the current shapeshift form
CancelUnitBuffCancels a buff on the player
GetWeaponEnchantInfoReturns information about temporary enchant-
ments on the player’s weapons
UnitAuraReturns information about buffs/debuffs on a unit
UnitBuffReturns information about a buff on a unit
UnitDebuffReturns information about a debuff on a unit
CVar Functions
GetCVarReturns the value of a configuration variable
GetCVarAbsoluteMaxReturns the absolute maximum value allowed for a
configuration variable
GetCVarAbsoluteMinReturns the absolute minimum value allowed for a
configuration variable
GetCVarBoolReturns the value of a configuration variable in a format
compatible with Lua conditional expressions
1036 Part IV Reference
GetCVarDefaultReturns the default value of a configuration variable
GetCVarInfoReturns information about a configuration variable
GetCVarMaxReturns the maximum recommended value for a configuration
variable
GetCVarMinReturns the minimum recommended value for a configuration
variable
RegisterCVarRegisters a configuration variable to be saved
SetCVarSets the value of a configuration variable
Calendar Functions
CalendarAddEventSaves the event recently created (and selected for edit-
ing) to the calendar
CalendarCanAddEventReturns whether the player can add an event to the
calendar
CalendarCanSendInviteReturns whether the player can invite others to a
calendar event
CalendarCloseEventDeselects (ends viewing/editing on) an event
CalendarContextDeselectEventClears the event selection used only for
CalendarContext functions
CalendarContextEventCanComplainReturns whether the player can report
an event invitation as spam
CalendarContextEventCanEditReturns whether the player can edit an
event
CalendarContextEventClipboardReturns whether the player can paste an
event
CalendarContextEventComplainReports an event invitation as spam
CalendarContextEventCopyCopies an event for later pasting
CalendarContextEventGetCalendarTypeReturns the type of a calendar
event
CalendarContextEventPastePastes a copied event into a given date
CalendarContextEventRemoveDeletes an event from the calendar
CalendarContextEventSignUpSigns the player up for a guild event
CalendarContextGetEventIndexReturns the month, day, and index of the
event selection used only for CalendarContext functions
CalendarContextInviteAvailableAccepts an event invitation
CalendarContextInviteDeclineDeclines an event invitation
Chapter 28 API Categories 1037
CalendarContextInviteIsPendingReturns whether the player has been
invited to an event and not yet responded
CalendarContextInviteModeratorStatusReturns the player’s moderator
status for an event
CalendarContextInviteRemoveRemoves an invitation from the player’s
calendar or removes the player from a guild event’s signup list
CalendarContextInviteStatusReturns the player’s invite status for an
event
CalendarContextInviteTypeReturns the invite type for an event
CalendarContextSelectEventSelects an event for use only with other
CalendarContext functions
CalendarDefaultGuildFilterReturns default options for the guild mem-
ber Mass Invite filter
CalendarEventAvailableAccepts invitation to the selected calendar event
CalendarEventCanEditReturns whether the player can edit the selected
calendar event
CalendarEventCanModerateReturns whether an event invitee can be
granted moderator authority
CalendarEventClearAutoApproveDisables the auto-approve feature (cur-
rently unused) for the selected calendar event
CalendarEventClearLockedUnlocks the selected calendar event
CalendarEventClearModeratorRemoves moderator status from a charac-
ter on the selected event’s invite/signup list
CalendarEventDeclineDeclines invitation to the selected calendar event
CalendarEventGetCalendarTypeReturns the type of the selected calendar
event
CalendarEventGetInviteReturns information about an entry in the
selected event’s invite/signup list
CalendarEventGetInviteResponseTimeReturns the time at which a char-
acter on the selected event’s invite/signup list responded
CalendarEventGetInviteSortCriterionReturns the current sort mode for
the event invite/signup list
CalendarEventGetNumInvitesReturns the number of characters on the
selected calendar event’s invite/signup list
CalendarEventGetRepeatOptionsReturns a list of localized event repeti-
tion option labels (currently unused)
1038 Part IV Reference
CalendarEventGetSelectedInviteReturns the index of the selected entry
on the selected event’s invite/signup list
CalendarEventGetStatusOptionsReturns a list of localized invite status
labels
CalendarEventGetTexturesReturns a list of instance names and icons for
dungeon or raid events
CalendarEventGetTypesReturns a list of event display style labels
CalendarEventHasPendingInviteReturns whether the player has been
invited to the selected event and not yet responded
CalendarEventHaveSettingsChangedReturns whether the selected event
has unsaved changes
CalendarEventInviteAttempts to invite a character to the selected event
CalendarEventIsModeratorReturns whether the player has moderator
status for the selected calendar event
CalendarEventRemoveInviteRemoves a character from the selected event’s
invite/signup list
CalendarEventSelectInviteSelects an entry in the selected event’s
invite/signup list
CalendarEventSetAutoApproveEnables the auto-approve feature (cur-
rently unused) for the selected calendar event
CalendarEventSetDateChanges the scheduled date of the selected calendar
event
CalendarEventSetDescriptionChanges the descriptive text for the se-
lected event
CalendarEventSetLockedLocks the selected calendar event
CalendarEventSetLockoutDateChanges the lockout date associated with
the selected event (currently unused)
CalendarEventSetLockoutTimeChanges the lockout time associated with
the selected event (currently unused)
CalendarEventSetModeratorGrants moderator status to a character on the
selected event’s invite/signup list
CalendarEventSetRepeatOptionChanges the repetition option for the
selected event (currently unused)
CalendarEventSetSizeChanges the maximum number of invites/signups
for the selected event (currently unused)
CalendarEventSetStatusSets the status of a character on the selected
event’s invite/signup list
Chapter 28 API Categories 1039
CalendarEventSetTextureIDChanges the raid or dungeon instance for the
selected event
CalendarEventSetTimeChanges the scheduled time of the selected event
CalendarEventSetTitleChanges the title for the selected event
CalendarEventSetTypeChanges the display type of the selected event
CalendarEventSignUpSigns the player up for the selected calendar event
CalendarEventSortInvitesSorts the event invite/signup list
CalendarGetAbsMonthReturns date information for a given month and
year
CalendarGetDateReturns the current date (in the server’s time zone)
CalendarGetDayEventReturns information about a calendar event on a
given day
CalendarGetEventIndexReturns the month, day, and index of the selected
calendar event
CalendarGetEventInfoReturns information about the selected calendar
event (for player/guild events)
CalendarGetFirstPendingInviteReturns the index of the first invitation
on a given day to which the player has not responded
CalendarGetHolidayInfoReturns additional information about a holiday
event
CalendarGetMaxCreateDateReturns the latest date for which events may
be scheduled
CalendarGetMaxDateReturns the latest date usable in the calendar system
CalendarGetMinDateReturns the earliest date usable in the calendar system
CalendarGetMinHistoryDateReturns the earliest date for which informa-
tion about past player events is available
CalendarGetMonthReturns information about a calendar month
CalendarGetMonthNamesReturns a list of localized month names
CalendarGetNumDayEventsReturns the number of calendar events on a
given day
CalendarGetNumPendingInvitesReturns the number of calendar invita-
tions to which the player has yet to respond
CalendarGetRaidInfoReturns information about a raid lockout or sched-
uled raid reset event
CalendarGetWeekdayNamesReturns a list of localized weekday names
1040 Part IV Reference
CalendarIsActionPendingReturns whether an update to calendar infor-
mation is in progress
CalendarMassInviteArenaTeamRepopulates the current event’s invite list
with members of one of the player’s arena teams
CalendarMassInviteGuildRepopulates the selected event’s invite list with
members of the player’s guild
CalendarNewEventCreates a new event and selects it for viewing/editing
CalendarNewGuildAnnouncementCreates a new guild announcement and
selects it for viewing/editing
CalendarNewGuildEventCreates a new guild event and selects it for view-
ing/editing
CalendarOpenEventSelects a calendar event for viewing/editing
CalendarRemoveEventRemoves the selected event invitation from the
player’s calendar or removes the player from the selected guild event’s
signup list
CalendarSetAbsMonthSets the calendar’s month to an absolute date
CalendarSetMonthSets the calendar’s month relative to its current month
CalendarUpdateEventSaves changes made to the selected event
CanEditGuildEventReturns whether the player is allowed to edit guild-
wide calendar events
OpenCalendarQueries the server for calendar status information
Camera Functions
CameraOrSelectOrMoveStartBegins camera movement or selection (equiv-
alent to left-clicking in the 3-D world)
CameraOrSelectOrMoveStopEnds action initiated by CameraOrSelectOr-
MoveStart
CameraZoomInZooms the camera in by a specified distance
CameraZoomOutZooms the camera out by a specified distance
FlipCameraYawRotates the camera around the player
IsMouselookingReturns whether mouselook mode is active
MouselookStartEnables mouselook mode, in which cursor movement
rotates the camera
MouselookStopDisables mouselook mode
MoveViewDownStartBegins orbiting the camera downward (to look
upward)
Chapter 28 API Categories 1041
MoveViewDownStopEnds camera movement initiated by MoveViewDownStart
MoveViewInStartBegins zooming the camera inward (towards/through
the player character)
MoveViewInStopEnds camera movement initiated by MoveViewInStart
MoveViewLeftStartBegins orbiting the camera around the player character
to the left
MoveViewLeftStopEnds camera movement initiated by MoveViewLeftStart
MoveViewOutStartBegins zooming the camera outward (away from the
player character)
MoveViewOutStopEnds camera movement initiated by MoveViewOutStart
MoveViewRightStartBegins orbiting the camera around the player charac-
ter to the right
MoveViewRightStopEnds camera movement initiated by MoveViewRight
Start
MoveViewUpStartBegins orbiting the camera upward (to look down)
MoveViewUpStopEnds camera movement initiated by MoveViewUpStart
NextViewMoves the camera to the next predefined setting
PrevViewMoves the camera to the previous predefined setting
ResetViewResets a saved camera setting to default values
SaveViewSaves the current camera settings
SetViewMoves the camera to a saved camera setting
Channel Functions
AddChatWindowChannelAdds a chat channel to the saved list of those
displayed in a chat window
ChannelBanBans a character from a chat channel
ChannelInviteInvites a character to join a chat channel
ChannelKickRemoves a player from the channel
ChannelModeratorGrants a character moderator status in a chat channel
ChannelMuteGrants a character ability to speak in a moderated chat channel
ChannelSilenceAllSilences a character for chat and voice on a channel
ChannelSilenceVoiceSilences the given character for voice chat on the
channel
ChannelToggleAnnouncementsEnables or disables printing of join/leave
announcements for a channel
1042 Part IV Reference
ChannelUnSilenceAllUnsilences a character for chat and voice on a
channel
ChannelUnSilenceVoiceUnsilences a character on a chat channel
ChannelUnbanLifts the ban preventing a character from joining a chat
channel
ChannelUnmoderatorRevokes moderator status from a character on a chat
channel
ChannelUnmuteRemoves a character’s ability to speak in a moderated chat
channel
ChannelVoiceOffDisables voice chat in a channel
ChannelVoiceOnEnables voice chat in a channel
CollapseChannelHeaderCollapses a group header in the chat channel
listing
DeclineInviteDeclines an invitation to a chat channel
DisplayChannelOwnerRequests information from the server about a chan-
nel’s owner
DisplayChannelVoiceOffDisables voice in a channel specified by its posi-
tion in the channel list display
DisplayChannelVoiceOnEnables voice in a channel specified by its position
in the channel list display
EnumerateServerChannelsReturns the available server channel names
ExpandChannelHeaderExpands a group header in the chat channel listing
GetActiveVoiceChannelReturns the currently active voice channel
GetChannelDisplayInfoReturns information about an entry in the channel
list display
GetChannelListReturns the list of the channels the player has joined
GetChannelNameReturns information about a chat channel
GetChannelRosterInfoReturns information about a character in a chat
channel in the channel list display
GetChatWindowChannelsReturns the saved list of channels to which a chat
window is subscribed
GetNumChannelMembersReturns the number of members in a chat channel
GetNumDisplayChannelsReturns the number of entries in the channel list
display
GetSelectedDisplayChannelReturns the selected channel in the channel
list display
Chapter 28 API Categories 1043
IsDisplayChannelModeratorReturns whether the player is a moderator of
the selected channel in the channel list display
IsDisplayChannelOwnerReturns whether the player is the owner of the
selected channel in the channel list display
IsSilencedReturns whether a character is silenced on a chat channel
JoinPermanentChannelJoins a channel, saving associated chat window
settings
JoinTemporaryChannelJoins a channel, but does not save associated chat
window settings
LeaveChannelByNameLeaves a chat channel
ListChannelByNameRequests the list of participants in a chat channel
ListChannelsRequests a list of channels joined by the player
RemoveChatWindowChannelRemoves a channel from a chat window’s list
of saved channel subscriptions
SetActiveVoiceChannelSets the currently active voice channel
SetActiveVoiceChannelBySessionIDSets the currently active voice chat
channel
SetChannelOwnerGives channel ownership to another character
SetChannelPasswordSets a password on a custom chat channel
SetSelectedDisplayChannelSelects a channel in the channel list display
Chat Functions
AddChatWindowChannelAdds a chat channel to the saved list of those
displayed in a chat window
AddChatWindowMessagesAdds a message type to the saved list of those
displayed in a chat window
CanComplainChatReturns whether a chat message can be reported as spam
ChangeChatColorChanges the color associated with a chat message type
ChatFrame_AddMessageEventFilterAdds a function to filter or alter mes-
sages to the chat display system
ChatFrame_GetMessageEventFiltersReturns the list of filters registered
for a chat event
ChatFrame_RemoveMessageEventFilterRemoves a previously set chat
message filter
ComplainChatReports a chat message as spam
1044 Part IV Reference
DoEmotePerforms a preset emote (with optional target)
GetChatTypeIndexReturns the numeric index corresponding to a chat
message type
GetChatWindowChannelsReturns the saved list of channels to which a chat
window is subscribed
GetChatWindowInfoReturns the saved settings for a chat window
GetChatWindowMessagesReturns the saved list of messages to which a chat
window is subscribed
GetDefaultLanguageReturns the name of the player character’s default
language
GetLanguageByIndexReturns the localized name of a player character
language
GetNumLanguagesReturns the number of languages the player character
can speak
LoggingChatEnables or disables saving chat text to a file
LoggingCombatEnables or disables saving combat log data to a file
RandomRollInitiates a public, server-side ‘‘dice roll’’
RemoveChatWindowChannelRemoves a channel from a chat window’s list
of saved channel subscriptions
RemoveChatWindowMessagesRemoves a message type from a chat window’s
list of saved message subscriptions
ResetChatColorsRemoves all saved color settings for chat message types,
resetting them to default values
ResetChatWindowsRemoves all saved chat window settings, resetting them
to default values
SendChatMessageSends a chat message
SetChatWindowAlphaSaves a chat window’s background opacity setting
SetChatWindowColorSaves a chat window’s background color setting
SetChatWindowDockedSaves whether a chat window should be docked
with the main chat window
SetChatWindowLockedSaves whether a chat window is locked
SetChatWindowNameSaves a chat window’s display name setting
SetChatWindowShownSaves whether a chat window should be shown
SetChatWindowSizeSaves a chat window’s font size setting
SetChatWindowUninteractableSaves whether a chat window is marked as
non-interactive
Chapter 28 API Categories 1045
Class Resource Functions
DestroyTotemDestroys a specific totem (or ghoul)
GetRuneCooldownReturns cooldown information about one of the player’s
rune resources
GetRuneCountReturns the number of available rune resources in one of the
player’s rune slots
GetRuneTypeReturns the type of one of the player’s rune resources
GetTotemInfoReturns information on a currently active totem (or ghoul)
GetTotemTimeLeftReturns the time remaining before a totem (or ghoul)
automatically disappears
TargetTotemTargets one of the player’s totems (or a Death Knight’s ghoul)
Client Control and Information Functions
CancelLogoutCancels a pending logout or quit
DownloadSettingsRestores game settings from a backup stored on the
server
ForceQuitImmediately exits World of Warcraft
GetAccountExpansionLevelReturns the most recent of WoW’s retail expan-
sion packs for which the player’s account is authorized
GetBuildInfoReturns the version information about the client
GetExistingLocalesReturns a list of installed localization packs for the
WoW client
GetGameTimeReturns the current realm (server) time
GetLocaleReturns a code indicating the localization currently in use by
the client
GetNetStatsReturns information about current network connection per-
formance
IsLinuxClientReturns whether the player is using the Linux game client
IsMacClientReturns whether the player is using the Mac OS X game client
IsWindowsClientReturns whether the player is using the Windows game
client
LogoutAttempts to log out and return to the character selection screen
NotWhileDeadErrorCauses the default UI to display an error message
indicating that actions are disallowed while the player is dead
1046 Part IV Reference
QuitAttempts to exit the World of Warcraft client
ReloadUIReloads the user interface
ScreenshotSaves an image of the current game display
SetEuropeanNumbersSets the decimal separator for displayed numbers
SetUIVisibilityEnables or disables display of UI elements in the 3-D
world
UploadSettingsStores a backup of game settings on the server
Combat Functions
AttackTargetBegins auto-attack against the player’s current target
StartAttackBegins auto-attack against a specified target
StopAttackStops auto-attack if active
UnitAffectingCombatReturns whether a unit is currently in combat
CombatLog Functions
CombatLogAddFilterAdds a filter to the combat log system
CombatLogAdvanceEntryAdvances the ‘‘cursor’’ position used by other
CombatLog functions
CombatLogClearEntriesRemoves all entries from the combat log
CombatLogGetCurrentEntryReturns the combat log event information for
the current entry and advances to the next entry
CombatLogGetNumEntriesReturns the number of available combat log
events
CombatLogGetRetentionTimeReturns the amount of time combat log
entries are stored
CombatLogResetFilterRemoves any filters applied to the combat log
CombatLogSetCurrentEntrySets the ‘‘cursor’’ position used by other Com-
batLog functions
CombatLogSetRetentionTimeSets the amount of time combat log entries
will be stored
CombatLog_Object_IsAReturns whether an entity from the combat log
matches a given filter
LoggingCombatEnables or disables saving combat log data to a file
UnitGUIDReturns a unit’s globally unique identifier
Chapter 28 API Categories 1047
Companion Functions
CallCompanionSummons a non-combat pet or mount
DismissCompanionUnsummons the current non-combat pet or mount
GetCompanionCooldownReturns cooldown information for a non-combat
pet or mount
GetCompanionInfoReturns information about a non-combat pet or mount
GetNumCompanionsReturns the number of mounts or non-combat pets the
player can summon
PickupCompanionPuts a non-combat pet or mount onto the cursor
Complaint Functions
CalendarContextEventCanComplainReturns whether the player can report
an event invitation as spam
CalendarContextEventComplainReports an event invitation as spam
CanComplainChatReturns whether a chat message can be reported as spam
CanComplainInboxItemReturns whether a mail message can be reported
as spam
ComplainChatReports a chat message as spam
ComplainInboxItemReports a mail message as spam
PlayerIsPVPInactiveReturns whether a battleground participant is inac-
tive (and eligible for reporting as AFK)
ReportPlayerIsPVPAFKReports a battleground participant as AFK
Container Functions
ContainerIDToInventoryIDReturns the inventoryID corresponding to a
given containerID
ContainerRefundItemPurchaseSells an item purchased with alternate cur-
rencybacktoavendor
EquipmentManager_UnpackLocationUnpacks an inventory location bitfield
into usable components
GetBagNameReturns the name of one of the player’s bags
GetContainerFreeSlotsReturns a list of open slots in a container
1048 Part IV Reference
GetContainerItemCooldownReturns cooldown information about an item
in the player’s bags
GetContainerItemDurabilityReturns durability status for an item in the
player’s bags
GetContainerItemGemsReturns the gems socketed in an item in the player’s
bags
GetContainerItemIDReturns the item ID of an item in the player’s bags
GetContainerItemInfoReturns information about an item in the player’s
bags
GetContainerItemLinkReturns a hyperlink for an item in the player’s bags
GetContainerItemPurchaseInfoReturns information about alternate cur-
rencies refunded for returning an item to vendors
GetContainerItemPurchaseItemReturns information about a specific cur-
rency refunded for returning an item to vendors
GetContainerNumFreeSlotsReturns the number of free slots in a container
and the types of items it can hold
GetContainerNumSlotsReturns the number of slots in one of the player’s
bags
GetItemFamilyReturns information about special bag types that can hold
a given item
PickupBagFromSlotPuts an equipped container onto the cursor
PickupContainerItemPicksupanitemfromorputsanitemintoaslotin
one of the player’s bags or other containers
PutItemInBackpackPuts the item on the cursor into the player’s backpack
PutItemInBagPuts the item on the cursor into the one of the player’s bags
or other containers
SetBagPortraitTextureSets a Texture object to display the icon of one of
the player’s bags
SocketContainerItemOpens an item from the player’s bags for socketing
SplitContainerItemPicks up only part of a stack of items from one of the
player’s bags or other containers
UseContainerItemActivate (as with right-clicking) an item in one of the
player’s bags
Currency Functions
ExpandCurrencyListExpands or collapses a list header in the Currency UI
GetArenaCurrencyReturns the player’s amount of arena points
Chapter 28 API Categories 1049
GetBackpackCurrencyInfoReturns information about a currency marked
for watching on the Backpack UI
GetContainerItemPurchaseInfoReturns information about alternate cur-
rencies refunded for returning an item to vendors
GetContainerItemPurchaseItemReturns information about a specific cur-
rency refunded for returning an item to vendors
GetCurrencyListInfoReturns information about a currency type (or head-
ers in the Currency UI)
GetCurrencyListSizeReturns the number of list entries to show in the
Currency UI
GetHonorCurrencyReturns the player’s amount of honor points
GetMaxArenaCurrencyReturns the maximum amount of arena points the
player can accrue
SetCurrencyBackpackSetsacurrencytypetobewatchedontheBackpack
UI
SetCurrencyUnusedMoves a currency type to or from the Unused curren-
cies list
Cursor Functions
AddTradeMoneyAdds the money currently on the cursor to the trade win-
dow
AutoEquipCursorItemEquips the item on the cursor
ClearCursorClears any contents attached to the cursor
ClickAuctionSellItemButtonPicksupanitemfromorputsaniteminto
the ‘‘Create Auction’’ slot
ClickSendMailItemButtonPicksupanitemfromorputsanitemintoan
attachment slot for sending mail
ClickSocketButtonPicks up or places a gem in the Item Socketing UI
ClickTargetTradeButtonInteracts with an item in a slot offered for trade
by the target
ClickTradeButtonPicksupanitemfromorputsaniteminaslotoffered
for trade by the player
CursorCanGoInSlotReturns whether the item on the cursor can be
equipped in an inventory slot
CursorHasItemReturns whether an item is on the cursor
1050 Part IV Reference
CursorHasMacroReturns whether a macro is on the cursor
CursorHasMoneyReturns whether an amount of the player’s money is on
the cursor
CursorHasSpellReturns whether a spell is on the cursor
DeleteCursorItemDestroys the item on the cursor
DropCursorMoneyDrops any money currently on the cursor, returning it to
where it was taken from
DropItemOnUnit‘‘Gives’’ the item on the cursor to another unit; results
vary by context
EquipCursorItemPuts the item on the cursor into a specific equipment slot
GetCursorInfoReturns information about the contents of the cursor
GetCursorMoneyReturns the amount of money currently on the cursor
GetCursorPositionReturns the absolute position of the mouse cursor
GetMouseFocusReturns the frame that is currently under the mouse, and
has mouse input enabled
HideRepairCursorReturns the cursor to normal mode after use of
ShowRepairCursor()
InRepairModeReturns whether the item repair cursor mode is currently
active
PickupActionPuts the contents of an action bar slot onto the cursor or the
cursor contents into an action bar slot
PickupBagFromSlotPuts an equipped container onto the cursor
PickupCompanionPuts a non-combat pet or mount onto the cursor
PickupContainerItemPicksupanitemfromorputsanitemintoaslotin
one of the player’s bags or other containers
PickupGuildBankItemPicksupanitemfromorputsanitemintotheguild
bank
PickupGuildBankMoneyPuts money from the guild bank onto the cursor
PickupInventoryItemPicksupanitemfromorputsanitemintoan
equipment slot
PickupItemPuts an arbitrary item onto the cursor
PickupMacroPuts a macro onto the cursor
PickupMerchantItemPuts an item available for purchase from a vendor
onto the cursor
PickupPetActionPuts the contents of a pet action slot onto the cursor or
the cursor contents into a pet action slot
Chapter 28 API Categories 1051
PickupPlayerMoneyPuts an amount of the player’s money onto the cursor
PickupSpellPuts a spell from the player’s or pet’s spellbook onto the
cursor
PickupStablePetPuts a pet from the stables onto the cursor
PickupTradeMoneyPuts money offered by the player for trade onto the
cursor
PlaceActionPuts the contents of the cursor into an action bar slot
PutItemInBackpackPuts the item on the cursor into the player’s backpack
PutItemInBagPuts the item on the cursor into one of the player’s bags or
other containers
ResetCursorReturns the cursor to its normal appearance (the glove pointer)
and behavior
SetCursorChanges the mouse cursor image
ShowBuybackSellCursorChanges the cursor to prepare for repurchasing
an item recently sold to a vendor
ShowContainerSellCursorChanges the cursor to prepare for selling an
item in the player’s bags to a vendor
ShowInventorySellCursorChanges the cursor to prepare for selling an
equipped item to a vendor
ShowMerchantSellCursorChanges the cursor to prepare for buying an item
from a vendor
ShowRepairCursorPuts the cursor in item repair mode
SplitContainerItemPicks up only part of a stack of items from one of the
player’s bags or other containers
SplitGuildBankItemPicks up only part of a stack of items from the guild
bank
Debugging and Profiling Functions
FrameXML_DebugEnables or disables logging of XML loading
GetAddOnCPUUsageReturns the amount of CPU time used by an addon
GetAddOnMemoryUsageReturns the amount of memory used by an addon
GetEventCPUUsageReturns information about the CPU usage of an event
GetFrameCPUUsageReturns information about CPU usage by a frame’s
script handlers
GetFramerateReturns the number of frames per second rendered by the
client
1052 Part IV Reference
GetFunctionCPUUsageReturns information about CPU usage by a function
GetNetStatsReturns information about current network connection
performance
GetScriptCPUUsageReturns the total CPU time used by the scripting
system
GetTaxiBenchmarkModeReturns whether flight path benchmark mode is
enabled
ResetCPUUsageResets CPU usage statistics
SetTaxiBenchmarkModeEnables or disables flight path benchmark mode
UpdateAddOnCPUUsageUpdates addon CPU profiling information
UpdateAddOnMemoryUsageUpdates addon memory usage information
debugprofilestartStarts/resets the high resolution profiling timer
debugprofilestopReturns the value of the profiling timer
debugstackReturns information about the current function call stack
geterrorhandlerReturns the current error handler function
issecurevariableReturns whether a variable is secure (and if not, which
addon tainted it)
seterrorhandlerChanges the error handler to a specified function
Duel Functions
AcceptDuelAccepts a proposed duel
CancelDuelCancels a proposed duel, or declines an offered duel
StartDuelChallenges another player to a duel
Equipment Manager Functions
CanUseEquipmentSetsReturns whether the player has enabled the equip-
ment manager
DeleteEquipmentSetDeletes an equipment set
EquipmentManagerClearIgnoredSlotsForSaveClears the list of equipment
slots to be ignored when saving sets
EquipmentManagergnoreSlotForSaveAdds an equipment slot to the list of
those ignored when saving sets
EquipmentManagerIsSlotIgnoredForSaveReturns whether the contents of
an equipment slot will be included when saving sets
Chapter 28 API Categories 1053
EquipmentManagerUnignoreSlotForSaveRemoves an equipment slot from
the list of those ignored when saving sets
EquipmentManager_UnpackLocationUnpacks an inventory location bitfield
into usable components
EquipmentSetContainsLockedItemsReturns whether an equipment set
contains locked items
GetEquipmentSetInfoReturns information about an equipment set (speci-
fied by index)
GetEquipmentSetInfoByNameReturns information about an equipment set
GetEquipmentSetItemIDsReturns a table listing the items in an equipment
set
GetEquipmentSetLocationsReturns a table listing the locations of the items
in an equipment set
GetNumEquipmentSetsReturns the number of saved equipment sets
PickupEquipmentSetPuts an equipment set (specified by index) on the
cursor
PickupEquipmentSetByNamePuts an equipment set on the cursor
RenameEquipmentSetChanges the name of a saved equipment set
SaveEquipmentSetSaves or creates an equipment set with the player’s
currently equipped items
UseEquipmentSetEquips the items in an equipment set
Faction Functions
CollapseAllFactionHeadersCollapses all headers and sub-headers in the
Reputation UI
CollapseFactionHeaderCollapses a given faction header or sub-header in
the Reputation UI
ExpandAllFactionHeadersExpands all headers and sub-headers in the
Reputation UI
ExpandFactionHeaderExpands a given faction header or sub-header in the
Reputation UI
FactionToggleAtWarToggles ‘‘at war’’ status for a faction
GetFactionInfoReturns information about a faction or header listing
GetNumFactionsReturns the number of entries in the Reputation UI
1054 Part IV Reference
GetSelectedFactionReturns which faction entry is selected in the
Reputation UI
GetWatchedFactionInfoReturns information about the ‘‘watched’’ faction
(displayed on the XP bar in the default UI)
IsFactionInactiveReturns whether a faction is flagged as ‘‘inactive’’
SetFactionActiveRemoves the ‘‘inactive’’ status from a faction
SetFactionInactiveFlags a faction as inactive
SetSelectedFactionSelects a faction in the Reputation UI
SetWatchedFactionIndexMakes a faction the ‘‘watched’’ faction (dis-
played on the XP bar in the default UI)
GM Survey Functions
GMSurveyAnswerReturns text of multiple-choice question answers in a GM
survey
GMSurveyAnswerSubmitSubmits an answer to a GM survey question
GMSurveyCommentSubmitSubmits a comment to the current GM survey
GMSurveyQuestionReturns the text of a specific question from a GM survey
GMSurveySubmitSubmits the current GM survey
GM Ticket Functions
DeleteGMTicketAbandons the currently pending GM ticket
GMResponseNeedMoreHelpRequests further GM interaction on a ticket to
which a GM has already responded
GMResponseResolveNotifies the server that the player’s GM ticket issue
has been resolved
GetGMTicketRequests GM ticket status from the server
NewGMTicketOpensanewGMsupportticket
StuckUses the auto-unstuck feature
UpdateGMTicketUpdates the open GM ticket with new text
Glyph Functions
GetGlyphLinkGets a hyperlink for the contents of a glyph socket
GetGlyphSocketInfoReturns information about a glyph socket and its
contents
Chapter 28 API Categories 1055
GlyphMatchesSocketReturns whether a socket is eligible for the glyph
currently awaiting a target
PlaceGlyphInSocketApplies the glyph currently awaiting a target to a
socket
RemoveGlyphFromSocketRemoves the glyph from a socket
SpellCanTargetGlyphReturns whether the spell currently awaiting a target
requires a glyph slot to be chosen
Guild Bank Functions
AutoStoreGuildBankItemWithdraws the item(s) from a slot in the guild
bank, automatically adding to the player’s bags
BuyGuildBankTabPurchases the next available guild bank tab
CanEditGuildTabInfoReturns whether the player is allowed to edit a guild
bank tab’s information
CanGuildBankRepairReturns whether the player is allowed to pay for
repairs using guild bank funds
CanWithdrawGuildBankMoneyReturns whether the player is allowed to
withdraw money from the guild bank
CloseGuildBankFrameEnds interaction with the guild bank vault
DepositGuildBankMoneyDeposits money into the guild bank
GetCurrentGuildBankTabReturns the currently selected guild bank tab
GetGuildBankItemInfoReturns information about the contents of a guild
bank item slot
GetGuildBankItemLinkReturns a hyperlink for an item in the guild bank
GetGuildBankMoneyReturns the amount of money in the guild bank
GetGuildBankMoneyTransactionReturns information about a transaction
in the guild bank money log
GetGuildBankTabCostReturns the cost of the next available guild bank tab
GetGuildBankTabInfoReturns information about a guild bank tab
GetGuildBankTabPermissionsReturns information about guild bank tab
privileges for the guild rank currently being edited
GetGuildBankTextReturns text associated with a guild bank tab
GetGuildBankTransactionReturns information about a transaction in the
log for a guild bank tab
GetGuildBankWithdrawLimitReturns the guild bank money withdrawal
limit for the guild rank currently being edited
1056 Part IV Reference
GetGuildBankWithdrawMoneyReturns the amount of money the player is
allowed to withdraw from the guild bank per day
GetNumGuildBankMoneyTransactionsReturns the number of transactions
in the guild bank money log
GetNumGuildBankTabsReturns the number of purchased tabs in the guild
bank
GetNumGuildBankTransactionsReturns the number of entries in a guild
bank tab’s transaction log
PickupGuildBankItemPicksupanitemfromorputsanitemintotheguild
bank
PickupGuildBankMoneyPuts money from the guild bank onto the cursor
QueryGuildBankLogRequests the item transaction log for a guild bank tab
from the server
QueryGuildBankTabRequests information about the contents of a guild
bank tab from the server
QueryGuildBankTextRequests guild bank tab info text from the server
SetCurrentGuildBankTabSelects a tab in the guild bank
SetGuildBankTabInfoSets the name and icon for a guild bank tab
SetGuildBankTabPermissionsChanges guild bank tab permissions for the
guild rank being edited
SetGuildBankTabWithdrawSets the number of item withdrawals allowed
per day for the guild rank being edited
SetGuildBankTextSets the info text for a guild bank tab
SetGuildBankWithdrawLimitSets the maximum amount of money with-
drawals per day allowed for the guild rank being edited
SplitGuildBankItemPicks up only part of a stack of items from the guild
bank
WithdrawGuildBankMoneyAttempts to withdraw money from the guild
bank
Guild Functions
AcceptGuildAccepts an invitation to join a guild
BuyGuildCharterPurchases a guild charter
CanEditGuildEventReturns whether the player is allowed to edit guild-
wide calendar events
Chapter 28 API Categories 1057
CanEditGuildInfoReturns whether the player is allowed to edit the guild
information text
CanEditMOTDReturns whether the player is allowed to edit the guild Mes-
sage of the Day
CanEditOfficerNoteReturns whether the player is allowed to edit guild
officer notes
CanEditPublicNoteReturns whether the player is allowed to edit guild
public notes
CanGuildDemoteReturns whether the player is allowed to demote lower
ranked guild members
CanGuildInviteReturns whether the player is allowed to invite new mem-
bers to his or her guild
CanGuildPromoteReturns whether the player is allowed to promote other
guild members
CanGuildRemoveReturns whether the player is allowed to remove members
from his or her guild
CanViewOfficerNoteReturns whether the player is allowed to view guild
officer notes
CloseGuildRegistrarEnds interaction with a guild registrar
CloseTabardCreationEnds interaction with the guild tabard creator
DeclineGuildDeclines an offered guild invitation
GetGuildCharterCostReturns the cost to purchase a guild charter
GetGuildEventInfoReturns information about an entry in the guild event
log
GetGuildInfoReturns a unit’s guild affiliation
GetGuildInfoTextReturns guild information text
GetGuildRosterInfoReturns information about the selected player in your
guild roster
GetGuildRosterLastOnlineReturns the amount of time since a guild mem-
ber was last online
GetGuildRosterMOTDReturns the Message of the Day for the player’s guild
GetGuildRosterSelectionReturns the index of the selected member in the
guild roster
GetGuildRosterShowOfflineReturns whether the guild roster lists offline
members
1058 Part IV Reference
GetGuildTabardFileNamesReturns the textures that comprise the player’s
guild tabard
GetNumGuildEventsReturns the number of entries in the guild event log
GetNumGuildMembersReturns the number of members in the guild roster
GetTabardCreationCostReturns the cost to create a guild tabard
GuildControlAddRankAdds a new rank to the player’s guild
GuildControlDelRankDeletes a guild rank
GuildControlGetNumRanksReturns the number of ranks in the guild
GuildControlGetRankFlagsReturns the list of privileges for the guild rank
being edited
GuildControlGetRankNameReturns the name of a guild rank
GuildControlSaveRankSaves changes to the guild rank being edited
GuildControlSetRankChooses a guild rank to edit
GuildControlSetRankFlagEnables or disables a privilege for the guild
rank being edited
GuildDemoteReduces a guild member’s rank by one
GuildDisbandDisbands the player’s guild
GuildInfoRequests guild information from the server
GuildInviteInvites a character to join the player’s guild
GuildLeaveLeaves the player’s current guild
GuildPromoteIncreases a guild member’s rank by one
GuildRosterRequests guild roster information from the server
GuildRosterSetOfficerNoteSets the officer note for a guild member
GuildRosterSetPublicNoteSets the public note for a guild member
GuildSetLeaderPromotes a member to guild leader
GuildSetMOTDSets the guild Message of the Day
GuildUninviteRemoves a character from the player’s guild
IsGuildLeaderReturns whether player is leader of his or her guild
IsInGuildReturns whether the player is in a guild
QueryGuildEventLogRequests guild event log information from the server
SetGuildInfoTextSets the guild information text
SetGuildRosterSelectionSelects a member in the guild roster
SetGuildRosterShowOfflineEnables or disables inclusion of offline mem-
bers in the guild roster listing
Chapter 28 API Categories 1059
SortGuildRosterSorts the guild roster
TurnInGuildCharterTurns in a completed guild charter
UnitIsInMyGuildReturns whether a unit is in the player’s guild
Hyperlink Functions
GetAchievementLinkReturns a hyperlink representing the player’s prog-
ress on an achievement
GetAuctionItemLinkReturns a hyperlink for an item in an auction listing
GetBuybackItemLinkReturns a hyperlink for an item recently sold to a
vendor and available to be repurchased
GetContainerItemLinkReturns a hyperlink for an item in the player’s bags
GetCursorInfoReturns information about the contents of the cursor
GetExistingSocketLinkReturns a hyperlink for a permanently sock-
eted gem
GetGlyphLinkGets a hyperlink for the contents of a glyph socket
GetGuildBankItemLinkReturns a hyperlink for an item in the guild bank
GetGuildBankTransactionReturns information about a transaction in the
log for a guild bank tab
GetInboxItemLinkReturns a hyperlink for an item attached to a message
in the player’s inbox
GetInventoryItemLinkReturns an item link for an equipped item
GetItemGemReturns information about gems socketed in an item
GetLootRollItemLinkReturns a hyperlink for an item currently up for loot
rolling
GetLootSlotLinkReturns a hyperlink for an item available as loot
GetMacroItemReturns information about the item used by a macro
GetMerchantItemLinkReturns a hyperlink for an item available for pur-
chase from a vendor
GetNewSocketLinkReturns a hyperlink for a gem added to a socket
GetQuestItemLinkReturns a hyperlink for an item in a questgiver dialog
GetQuestLinkReturns a hyperlink for an entry in the player’s quest log
GetQuestLogItemLinkReturns a hyperlink for an item related to the
selected quest in the quest log
GetSendMailItemLinkReturns a hyperlink for an item attached to the
outgoing message
1060 Part IV Reference
GetSpellLinkReturns a hyperlink for a spell
GetTalentLinkReturns a hyperlink for a talent
GetTradePlayerItemLinkReturns a hyperlink for an item offered for trade
by the player
GetTradeSkillItemLinkReturns a hyperlink for the item created by a
tradeskill recipe
GetTradeSkillListLinkReturns a hyperlink to the player’s list of recipes
for the current trade skill
GetTradeSkillReagentItemLinkReturns a hyperlink for a reagent in a
tradeskill recipe
GetTradeSkillRecipeLinkReturns hyperlink for a tradeskill recipe
GetTradeTargetItemLinkReturns a hyperlink for an item offered for trade
by the target
GetTrainerServiceItemLinkReturns a hyperlink for the item associated
with a trainer service
In-game Movie Playback Functions
GameMovieFinishedEnds in-game movie playback
GetMovieResolutionReturns the horizontal resolution available for dis-
playing movie content
InCinematicReturns whether an in-game cinematic is playing
OpeningCinematicDisplays the introductory cinematic for the player’s race
StopCinematicExits a currently playing in-game cinematic
Inspect Functions
CanInspectReturns whether a unit can be inspected
ClearInspectPlayerEnds inspection of another character
GetInspectArenaTeamDataReturns arena team information about the cur-
rently inspected unit
GetInspectHonorDataReturns PvP honor information about the currently
inspected unit
HasInspectHonorDataReturns whether PvP honor and arena data for the
currently inspected unit has been downloaded from the server
NotifyInspectMarks a unit for inspection and requests talent data from
the server
Chapter 28 API Categories 1061
RequestInspectHonorDataRequests PvP honor and arena data from the
server for the currently inspected unit
Instance Functions
CanShowResetInstancesReturns whether the player can reset instances
GetInstanceBootTimeRemainingReturns the amount of time left until the
player is removed from the current instance
GetInstanceDifficultyReturns difficulty setting for the current dun-
geon/raid instance
GetInstanceInfoReturns instance information about the current area
GetInstanceLockTimeRemainingReturns time remaining before the player
is saved to a recently entered instance
GetNumSavedInstancesReturns the number of instances to which the player
is saved
GetNumWorldStateUIReturns the number of world state UI elements
GetSavedInstanceInfoReturns information on a specific instance to which
the player is saved
GetWorldStateUIInfoReturns information about a world state UI element
IsInInstanceReturns whether the player is in an instance (and its type if
applicable)
RequestRaidInfoRequests information about saved instances from the
server
ResetInstancesResets all non-saved instances associated with the player
RespondInstanceLockAllows leaving a recently entered instance to which
the player would otherwise be saved
SetDungeonDifficultySets the player’s 5 player dungeon difficulty pref-
erence
SetRaidDifficultySets the player’s raid dungeon difficulty preference
Inventory Functions
AutoEquipCursorItemEquips the item on the cursor
BankButtonIDToInvSlotIDReturns the inventoryID corresponding to a
bank item or bag slot
CancelPendingEquipCancels equipping a bind-on-equip item
ContainerIDToInventoryIDReturns the inventoryID corresponding to a
given containerID
1062 Part IV Reference
CursorCanGoInSlotReturns whether the item on the cursor can be equip-
pedinaninventoryslot
EquipCursorItemPuts the item on the cursor into a specific equipment slot
EquipItemByNameAttempts to equip an arbitrary item
EquipPendingItemConfirms equipping a bind-on-equip item
EquipmentManager_UnpackLocationUnpacks an inventory location bitfield
into usable components
GetInventoryAlertStatusReturns the durability warning status of an
equipped item
GetInventoryItemBrokenReturns whether an equipped item is broken
GetInventoryItemCooldownReturns cooldown information about an
equipped item
GetInventoryItemCountReturns the number of items stacked in an inven-
tory slot
GetInventoryItemDurabilityReturns the current durability level of an
equipped item
GetInventoryItemGemsReturns the gems socketed in an equipped item
GetInventoryItemIDReturns the item ID of an equipped item
GetInventoryItemLinkReturns an item link for an equipped item
GetInventoryItemQualityReturns the quality level of an equipped item
GetInventoryItemTextureReturns the icon texture for an equipped item
GetInventoryItemsForSlotReturns a list of items that can be equipped in
a given inventory slot
GetInventorySlotInfoReturns information about an inventory slot
IsEquippedItemReturns whether an item is currently equipped
IsEquippedItemTypeReturns whether any items of a given type are cur-
rently equipped
IsInventoryItemLockedReturns whether an inventory slot is locked
KeyRingButtonIDToInvSlotIDReturns the inventoryID corresponding to
a slot in the keyring
PickupInventoryItemPicksupanitemfromorputsanitemintoan
equipment slot
SetInventoryPortraitTextureSets a Texture object to display the icon of
an equipped item
SocketInventoryItemOpens an equipped item for socketing
UseInventoryItemActivates (as with right-clicking) an equipped item
Chapter 28 API Categories 1063
Item Text Functions
CloseItemTextEnds interaction with a text object or item
ItemTextGetCreatorReturns the original author of the currently viewed
text item
ItemTextGetItemReturns the name of the currently viewed text item
ItemTextGetMaterialReturns display style information for the currently
viewed text item
ItemTextGetPageReturns the current page number in the currently viewed
text item
ItemTextGetTextReturns the text of the currently viewed text item
ItemTextHasNextPageReturns whether the currently viewed text item has
additional pages
ItemTextNextPageMoves to the next page in the currently viewed text item
ItemTextPrevPageMoves to the previous page in the currently viewed
text item
Item Functions
BindEnchantConfirms enchanting an item (when the item will become
soulbound as a result)
CancelPendingEquipCancels equipping a bind-on-equip item
ConfirmBindOnUseConfirms using an item, if using the item causes it to
become soulbound
CursorHasItemReturns whether an item is on the cursor
DeleteCursorItemDestroys the item on the cursor
EndBoundTradeableConfirms taking an action which renders a looted Bind
on Pickup item non-tradeable
EndRefundConfirms taking an action which renders a purchased item
non-refundable
EquipItemByNameAttempts to equip an arbitrary item
EquipPendingItemConfirms equipping a bind-on-equip item
GetItemCooldownReturns cooldown information about an arbitrary item
GetItemCountReturns information about how many of a given item the
player has or on remaining item charges
1064 Part IV Reference
GetItemFamilyReturns information about special bag types that can hold
a given item
GetItemGemReturns information about gems socketed in an item
GetItemIconReturns the path to an icon texture for the item
GetItemInfoReturns information about an item, by name, link or ID
GetItemQualityColorReturns color values for use in displaying items of a
given quality
GetItemSpellReturns information about the spell cast by an item’s ‘‘Use:’’
effect
GetItemStatDeltaReturns a summary of the difference in stat bonuses
between two items
GetItemStatsReturns a summary of an item’s stat bonuses
GetItemUniquenessReturns information about uniqueness restrictions for
equipping an item
IsConsumableItemReturns whether an item is consumable
IsCurrentItemReturns whether an item is being used
IsDressableItemReturns whether an item’s appearance can be previewed
using the Dressing Room feature
IsEquippableItemReturns whether an item can be equipped
IsEquippedItemReturns whether an item is currently equipped
IsEquippedItemTypeReturns whether any items of a given type are cur-
rently equipped
IsHarmfulItemReturns whether an item can be used against hostile units
IsHelpfulItemReturns whether an item can be used on the player or
friendly units
IsItemInRangeReturns whether the player is in range to use an item on a
unit
IsUsableItemReturns whether an item can currently be used
ItemHasRangeReturns whether an item has a range limitation for its use
PickupItemPuts an arbitrary item onto the cursor
ReplaceEnchantConfirms replacing an existing enchantment
SpellCanTargetItemReturns whether the spell currently awaiting a target
requires an item to be chosen
SpellTargetItemCasts the spell currently awaiting a target on an item
UseItemByNameUses an arbitrary item (optionally on a specified unit)
Chapter 28 API Categories 1065
Keybind Functions
ClearOverrideBindingsClears any registered override bindings for a
given owner
GetBindingReturns information about a key binding
GetBindingActionReturns the action bound to a key or key combination
GetBindingByKeyReturns the binding bound to a key or key combination
GetBindingKeyReturns the key combinations for a given binding command
GetCurrentBindingSetReturns which set of key bindings is currently in
use
GetNumBindingsReturns the number of entries in the key bindings list
LoadBindingsLoads a set of key bindings
RunBindingRuns the script associated with a key binding action
SaveBindingsSaves the current set of key bindings
SetBindingBinds a key combination to a binding command
SetBindingClickBinds a key combination to ‘‘click’’ a Button object
SetBindingItemBinds a key combination to use an item in the player’s
possession
SetBindingMacroBinds a key combination to run a macro
SetBindingSpellBinds a key combination to cast a spell
SetMouselookOverrideBindingOverrides the default mouselook bindings
to perform another binding with the mouse buttons
SetOverrideBindingSets an override binding for a binding command
SetOverrideBindingClickSets an override binding to ‘‘click’’ a Button
object
SetOverrideBindingItemSets an override binding to use an item in the
player’s possession
SetOverrideBindingMacroSets an override binding to run a macro
SetOverrideBindingSpellSets an override binding to a specific spell
Keyboard Functions
GetCurrentKeyBoardFocusReturns the frame currently handling keyboard
input
IsAltKeyDownReturns whether an Alt key on the keyboard is held down
1066 Part IV Reference
IsControlKeyDownReturns whether a Control key on the keyboard is held
down
IsLeftAltKeyDownReturns whether the left Alt key is currently held down
IsLeftControlKeyDownReturns whether the left Control key is held down
IsLeftShiftKeyDownReturns whether the left Shift key on the keyboard is
held down
IsModifierKeyDownReturns whether a modifier key is held down
IsRightAltKeyDownReturns whether the right Alt key is currently held
down
IsRightControlKeyDownReturns whether the right Control key on the
keyboard is held down
IsRightShiftKeyDownReturns whether the right shift key on the keyboard
is held down
IsShiftKeyDownReturns whether a Shift key on the keyboard is held down
Knowledge-base Functions
KBArticle_BeginLoadingRequests a specific knowledge base article from
the server
KBArticle_GetDataReturns information about the last requested know-
ledge base article
KBArticle_IsLoadedReturns whether the requested knowledge base arti-
cle has been loaded
KBQuery_BeginLoadingQueries the knowledge base server for articles
KBQuery_GetArticleHeaderCountReturns the number of articles on the
current knowledge base search result page
KBQuery_GetArticleHeaderDataReturns information about an article
returned in a knowledge base query
KBQuery_GetTotalArticleCountReturns the total number of articles
returned for the given query
KBQuery_IsLoadedReturns whether results of a knowledge base query
have been loaded
KBSetup_BeginLoadingLoads a maximum number of ‘‘Top Issues’’ from a
given page
KBSetup_GetArticleHeaderCountReturns the number of ‘‘Top Issues’’ arti-
cles on the current page
KBSetup_GetArticleHeaderDataReturns header information about a ‘‘Top
Issue’’ article
Chapter 28 API Categories 1067
KBSetup_GetCategoryCountReturns the number of available knowledge
base categories
KBSetup_GetCategoryDataReturns information about a knowledge base
category
KBSetup_GetLanguageCountReturns the number of available knowledge
base languages
KBSetup_GetLanguageDataReturns information about a given knowledge
base language
KBSetup_GetSubCategoryCountReturns the number of available subcate-
gories for a given category
KBSetup_GetSubCategoryDataReturns information about a knowledge
base subcategory
KBSetup_GetTotalArticleCountReturns the number of ‘‘Top Issues’’ arti-
cles
KBSetup_IsLoadedReturns whether the knowledge base default query has
completed successfully
KBSystem_GetMOTDReturns the currently knowledge base MOTD
KBSystem_GetServerNoticeReturns the text of the knowledge base server
system notice
KBSystem_GetServerStatusReturns the knowledge base server system
status message
Limited Play Time Functions
GetBillingTimeRestedReturns the amount of time for which the player
must be offline in order to lift play time restrictions
NoPlayTimeReturns whether the player has exceeded the allowed play time
limit
PartialPlayTimeReturns whether the player is near the allowed play time
limit
Locale-specific Functions
DeclineNameReturns suggested declensions for a name
FillLocalizedClassListFills a table with localized class names keyed by
non-localized class tokens
GetNumDeclensionSetsReturns the number of suggested declension sets
for a name
1068 Part IV Reference
Looking For Group Functions
AcceptLFGMatchAccepts a proposed LFG match
CanSendLFGQueryReturns whether the player can perform a given LFM
query
CancelPendingLFGCancels active LFG searches, removing the player from
the LFG queue and declining any automatic group invitations
ClearLFGAutojoinDisables the option to automatically join a group match-
ing current LFG criteria
ClearLFMAutofillDisables the option to automatically fill the player’s
group when Looking for More
ClearLookingForGroupCancels active LFG searches, removing the player
from the LFG queue
ClearLookingForMoreCancels active LFM searches, removing the player
from the LFG queue
DeclineLFGMatchDeclines a proposed LFG match
GetLFGPartyResultsReturns information about a member of a party in
Looking for More results
GetLFGResultsReturns information about a character in the Looking for
More results listing
GetLFGRolesReturns the group roles for which the player has signed up in
the LFG system
GetLFGStatusTextReturns information about the player’s status in the LFG
auto-join or LFM auto-fill queues
GetLFGTypeEntriesReturns a list of LFG entries (dungeons, zones, quests,
etc.) for a given type
GetLFGTypesReturns a list of LFG query types
GetLookingForGroupReturns information about the player’s status in the
LFG system
GetNumLFGResultsReturns the number of results from an LFM query
IsInLFGQueueReturns whether the player is currently queued for automat-
ically joining/filling a group
LFGQueryRequests Looking for More information from the server
SetLFGAutojoinEnables the option to automatically join a group matching
current LFG criteria
SetLFGCommentAssociates a brief text comment with the player’s listing in
the LFG system
Chapter 28 API Categories 1069
SetLFGRolesSets group roles for which to advertise the player in the LFG
system
SetLFMAutofillEnables the option to automatically fill the player’s group
when Looking for More
SetLFMTypeSets the type for LFM queries
SetLookingForGroupAdds the player to the LFG system for one of three
objectives
SetLookingForMoreSets up a Looking for More query
SortLFGSets the sort order for Looking for More results
Loot Functions
CloseLootEnds interaction with a lootable corpse or object
ConfirmLootRollConfirms the player’s intent regarding an item up for
loot rolling
ConfirmLootSlotConfirms picking up an item available as loot
GetLootMethodReturns information about the current loot method in a
party or raid
GetLootRollItemInfoReturns information about an item currently up for
loot rolling
GetLootRollItemLinkReturns a hyperlink for an item currently up for loot
rolling
GetLootRollTimeLeftReturns the amount of time remaining before loot
rolling for an item expires
GetLootSlotInfoReturns information about an item available
GetLootSlotLinkReturns a hyperlink for an item available as loot
GetLootThresholdReturns the threshold used for Master Looter, Group
Loot, and Need Before Greed loot methods
GetMasterLootCandidateReturns information about a given loot candidate
GetNumLootItemsReturns the number of items available to be looted
GetOptOutOfLootReturns whether the player has opted out of loot rolls
GiveMasterLootAwards a loot item to a group member
IsFishingLootReturns whether the currently displayed loot came from
fishing
LootSlotAttempts to pick up an item available as loot
1070 Part IV Reference
LootSlotIsCoinReturns whether a loot slot contains money
LootSlotIsItemReturns whether a loot slot contains an item
RollOnLootRegister the player’s intent regarding an item up for loot rolling
SetLootMethodSets the loot method for a party or raid group
SetLootPortraitSets a Texture object to show the appropriate portrait
image when looting
SetLootThresholdSets the threshold used for Master Looter, Group Loot,
and Need Before Greed loot methods
SetOptOutOfLootChanges the player’s preference to opt out of loot rolls
Lua Library Functions
absReturns the absolute value of a number
assertCauses a Lua error if a condition is failed
ceilReturns the smallest integer larger than or equal to a number
collectgarbageInterface to the Lua garbage collector
dateReturns a formatted date/time string for a date (or the current date)
degConverts an angle measurement in radians to degrees
difftimeReturns the number of seconds between two time values
errorCauses a Lua error message
expReturns the value of the exponential function for a number
floorReturns the largest integer smaller than or equal to a number
formatReturns a formatted string containing specified values
frexpReturns the normalized fraction and base-2 exponent for a number
getfenvReturns the environment for a function (or the global environment)
getmetatableReturns an object’s metatable
gmatchReturns an iterator function for finding pattern matches in a string
gsubReturns a string in which occurrences of a pattern are replaced
ipairsReturns an iterator function for integer keys in a table
ldexpReturns the number generated by a normalized fraction and base-2
exponent
loadstringLoads and compiles Lua source code
logReturns the natural logarithm of a number
log10Returns the base-10 logarithm of a number
Chapter 28 API Categories 1071
maxReturns the greatest of a list of numbers
minReturns the least of a list of numbers
modReturns the remainder from division of two numbers
nextReturns the next key/value pair in a table
pairsReturns an iterator function for a table
pcallExecutes a function in protected mode
radConverts an angle specified in degrees to radians
randomGenerates a pseudo-random number
rawequalReturns whether two values are equal without invoking any
metamethods
rawgetReturns the real value associated with a key in a table without
invoking any metamethods
rawsetSets the value associated with a key in a table without invoking any
metamethods
selectReturns one or more values from a list (...), or the number of
values in a list
setfenvSets the environment to be used by a function
setmetatableSets the metatable for a table
sortSorts a table
sqrtReturns the square root of a number
strbyteReturns the numeric code for one or more characters in a string
strcharReturns the character(s) for one or more numeric codes
strfindReturns information about matches for a pattern in a string
strlenReturns the number of characters in a string
strlowerReturns a copy of a string with all uppercase letters converted to
lowercase
strmatchReturns the matches for a pattern in a string
strrepReturns a string produced by a number of repetitions of another
string
strrevReturns the reverse of a string
strsubReturns a substring of a string
strupperReturns a copy of a string with all lowercase letters converted to
uppercase
timeReturns the numeric time value for a described date/time (or the
current time)
1072 Part IV Reference
tinsertInserts a value into a table
tonumberReturns the numeric value of a string
tostringReturns a string representation of a value
tremoveRemoves an element from a table
typeReturns a string describing the data type of a value
unpackReturns the list of elements in a table
xpcallExecutes a function in protected mode with a custom error handler
Mac Client Functions
IsMacClientReturns whether the player is using the Mac OS X game client
MovieRecording_CancelCancels video recording and compression
MovieRecording_DataRateReturns the data rate required for a given set of
video recording parameters
MovieRecording_DeleteMovieDeletes an uncompressed movie
MovieRecording_GetAspectRatioReturns the aspect ratio of the game dis-
play
MovieRecording_GetMovieFullPathReturns a path to the movie currently
being recorded or compressed
MovieRecording_GetProgressReturns information about movie compres-
sion progress
MovieRecording_GetTimeReturns the amount of time since video recording
was last started
MovieRecording_GetViewportWidthReturns the current width of the game
display
MovieRecording_IsCodecSupportedReturns whether a video codec is sup-
ported on the current system
MovieRecording_IsCompressingReturns whether a movie file is currently
being compressed
MovieRecording_IsCursorRecordingSupportedReturns whether the cur-
rent system supports recording the mouse cursor in movies
MovieRecording_IsRecordingReturns whether movie recording is cur-
rently in progress
MovieRecording_IsSupportedReturns whether movie recording is sup-
ported on the current system
MovieRecording_MaxLengthReturns the maximum length of recorded
video for a given set of video recording parameters
Chapter 28 API Categories 1073
MovieRecording_QueueMovieToCompressQueues an uncompressed movie
for compression
MovieRecording_SearchUncompressedMovieEnables or disables a search
for uncompressed movies
MovieRecording_ToggleBegins or ends video recording
MovieRecording_ToggleGUIEnables or disables inclusion of UI elements in
a video recording
MusicPlayer_BackTrackCauses iTunes to return to the previous track
played
MusicPlayer_NextTrackCauses iTunes to play the next track in sequence
MusicPlayer_PlayPauseCauses iTunes to start or pause playback
MusicPlayer_VolumeDownCauses iTunes to lower its playback volume
MusicPlayer_VolumeUpCauses iTunes to raise its playback volume
Macro Functions
CreateMacroCreates a new macro
CursorHasMacroReturns whether a macro is on the cursor
DeleteMacroDeletes a macro
EditMacroChanges the name, icon, and/or body of a macro
GetMacroBodyReturns the body text of a macro
GetMacroIconInfoReturns the texture for a macro icon option
GetMacroIndexByNameReturns the index of a macro specified by name
GetMacroInfoReturns information about a macro
GetMacroItemReturns information about the item used by a macro
GetMacroItemIconInfoReturns the texture for an item icon
GetMacroSpellReturns information about the spell cast by a macro
GetNumMacroIconsReturns the number of available macro icons
GetNumMacroItemIconsReturns the number of available item icons
GetNumMacrosReturns the number of macros the player has stored
GetRunningMacroReturns the index of the currently running macro
GetRunningMacroButtonReturns the mouse button that was used to acti-
vate the running macro
PickupMacroPuts a macro onto the cursor
RunMacroRuns a macro
RunMacroTextRuns arbitrary text as a macro
1074 Part IV Reference
SecureCmdOptionParseReturns the action (and target, if applicable) for a
secure macro command
SetMacroItemChanges the item used for dynamic feedback for a macro
SetMacroSpellChanges the spell used for dynamic feedback for a macro
StopMacroStops execution of a running macro
Mail Functions
AutoLootMailItemAutomatically takes any attached items and money
from a mail message
CanComplainInboxItemReturns whether a mail message can be reported
as spam
CheckInboxRequests information on the player’s mailbox contents from
the server
ClearSendMailClears any text, items, or money from the mail message to
be sent
ClickSendMailItemButtonPicksupanitemfromorputsanitemintoan
attachment slot for sending mail
CloseMailEnds interaction with a mailbox
ComplainInboxItemReports a mail message as spam
DeleteInboxItemDeletes a message from the player’s inbox
GetInboxHeaderInfoReturns information about a message in the player’s
inbox
GetInboxInvoiceInfoReturns auction house invoice information for a mail
message
GetInboxItemReturns information for an item attached to a message in the
player’s inbox
GetInboxItemLinkReturns a hyperlink for an item attached to a message
in the player’s inbox
GetInboxNumItemsReturns the number of messages in the player’s inbox
GetInboxTextReturns information about the text of an inbox message
GetLatestThreeSendersReturns the names of the last three senders of new
mail
GetSendMailCODReturns the Cash-On-Delivery cost of the outgoing mes-
sage
GetSendMailItemReturns information for an item attached to the outgoing
message
Chapter 28 API Categories 1075
GetSendMailItemLinkReturns a hyperlink for an item attached to the
outgoing message
GetSendMailMoneyReturns the amount of money to be sent with the out-
going message
GetSendMailPriceReturns the cost to send the outgoing mail message
HasNewMailReturns whether the player has received new mail since last
visiting a mailbox
InboxItemCanDeleteReturns whether a message in the player’s inbox can
be deleted
ReturnInboxItemReturns a message in the player’s inbox to its sender
SendMailSends the outgoing message
SetSendMailCODSets the Cash-On-Delivery cost of the outgoing message
SetSendMailMoneySets the amount of money to be sent with the outgoing
message
SetSendMailShowingEnables or disables shortcuts for attaching items to
outgoing mail
TakeInboxItemRetrieves an item attachment from a message in the player’s
inbox (accepting COD charges if applicable)
TakeInboxMoneyRetrieves any money attached to a message in the player’s
inbox
TakeInboxTextItemRequests a copy of a message’s body text as an item
Map Functions
ClickLandmarkProcesses a hyperlink associated with a map landmark
GetBattlefieldVehicleInfoReturns information about special vehicles in
the current zone
GetCorpseMapPositionReturns the position of the player’s corpse on the
world map
GetCurrentMapAreaIDReturns an ID number for the current map zone
GetCurrentMapContinentReturns the current world map continent
GetCurrentMapDungeonLevelReturns which map image is currently sele-
cted on the world map (for zones which use more than one map
image)
GetCurrentMapZoneReturns the current world map zone
GetDeathReleasePositionReturns the location of the graveyard where the
player’s spirit will appear upon release
1076 Part IV Reference
GetMapContinentsReturns a list of map continents’ names
GetMapInfoReturns information about the current world map texture
GetMapLandmarkInfoReturns information about a map landmark
GetMapOverlayInfoReturns information about a world map overlay
GetMapZonesReturns the map zones for a given continent
GetNumBattlefieldVehiclesReturns the number of special vehicles in the
current zone
GetNumDungeonMapLevelsReturns the number of map images for the world
map’s current zone
GetNumMapLandmarksReturns the number of landmarks on the world map
GetNumMapOverlaysReturns the number of overlays for the current world
map zone
GetPlayerFacingReturns the player’s orientation (heading)
GetPlayerMapPositionReturns the position of the player’s corpse on the
world map
GetWintergraspWaitTimeReturns the amount of time remaining until the
next PvP event in the Wintergrasp zone
ProcessMapClickPossibly changes the WorldMap based on a mouse click
SetDungeonMapLevelSets the world map to display a certain map image
(for zones that use multiple map images)
SetMapToCurrentZoneSets the world map to show the zone in which the
player is located
SetMapZoomSets the world map to show a specific zone or continent
UpdateMapHighlightReturns information about the texture used for high-
lighting zones in a continent map on mouseover
ZoomOutSets the world map to show the area containing its current area
Merchant Functions
BuyMerchantItemPurchases an item available from a vendor
BuybackItemRepurchases an item recently sold to a vendor
CanMerchantRepairReturns whether the vendor with whom the player is
currently interacting can repair equipment
CloseMerchantEnds interaction with a vendor
ContainerRefundItemPurchaseSells an item purchased with alternate cur-
rencybacktoavendor
Chapter 28 API Categories 1077
EndBoundTradeableConfirms taking an action which renders a looted Bind
on Pickup item non-tradeable
EndRefundConfirms taking an action which renders a purchased item
non-refundable
GetBuybackItemInfoReturns information about an item recently sold to a
vendor and available to be repurchased
GetBuybackItemLinkReturns a hyperlink for an item recently sold to a
vendor and available to be repurchased
GetContainerItemPurchaseInfoReturns information about alternate cur-
rencies refunded for returning an item to vendors
GetContainerItemPurchaseItemReturns information about a specific cur-
rency refunded for returning an item to vendors
GetMerchantItemCostInfoReturns information about alternate currencies
required to purchase an item from a vendor
GetMerchantItemCostItemReturns information about currency items req-
uired to purchase an item from a vendor
GetMerchantItemInfoReturns information about an item available for
purchase from a vendor
GetMerchantItemLinkReturns a hyperlink for an item available for pur-
chase from a vendor
GetMerchantItemMaxStackReturns the maximum number of an item all-
owed in a single purchase
GetMerchantNumItemsReturns the number of different items available for
purchase from a vendor
GetNumBuybackItemsReturns the number of items recently sold to a vendor
and available to be repurchased
GetRepairAllCostReturns the cost to repair all of the player’s damaged
items
InRepairModeReturns whether the item repair cursor mode is currently
active
PickupMerchantItemPuts an item available for purchase from a vendor
onto the cursor
RepairAllItemsAttempts to repair all of the player’s damaged items
ShowContainerSellCursorChanges the cursor to prepare for selling an
item in the player’s bags to a vendor
ShowRepairCursorPuts the cursor in item repair mode
1078 Part IV Reference
Modified Click Functions
GetModifiedClickReturns the keys/buttons bound for a modified click
action
GetModifiedClickActionReturns the token identifying a modified click
action
GetNumModifiedClickActionsReturns the number of modified click act-
ions registered
IsModifiedClickDetermines if the modifiers specified in the click-type
had been held down while the button click occurred
SetModifiedClickSets a modified click for a given action
Money Functions
AddTradeMoneyAdds the money currently on the cursor to the trade win-
dow
CanWithdrawGuildBankMoneyReturns whether the player is allowed to
withdraw money from the guild bank
CursorHasMoneyReturns whether an amount of the player’s money is on
the cursor
DepositGuildBankMoneyDeposits money into the guild bank
DropCursorMoneyDrops any money currently on the cursor, returning it to
where it was taken from
GetCoinIconReturns an icon representing an amount of money
GetCoinTextReturns a localized string describing an amount of money
GetCoinTextureStringReturns a string with embedded coin icons describ-
ing an amount of money
GetCursorMoneyReturns the amount of money currently on the cursor
GetMoneyReturns the total amount of money currently in the player’s
possession
GetPlayerTradeMoneyReturns the amount of money offered for trade by
the player
GetQuestLogRequiredMoneyReturns the amount of money required for the
selected quest in the quest log
GetQuestLogRewardMoneyReturns the money reward for the selected quest
in the quest log
Chapter 28 API Categories 1079
GetSendMailMoneyReturns the amount of money to be sent with the out-
going message
GetTargetTradeMoneyReturns the amount of money offered for trade by
the target
PickupGuildBankMoneyPuts money from the guild bank onto the cursor
PickupPlayerMoneyPuts an amount of the player’s money onto the cursor
PickupTradeMoneyPuts money offered by the player for trade onto the
cursor
SetSendMailMoneySets the amount of money to be sent with the outgoing
message
SetTradeMoneyOffers an amount of money for trade
WithdrawGuildBankMoneyAttempts to withdraw money from the guild
bank
Movement Functions
AscendStopStops movement initiated by JumpOrAscendStart
DescendStopStops movement initiated by SitStandOrDescendStart
FollowUnitCauses the player character to automatically follow another
unit
InteractUnitInteracts with (as with right-clicking on) a unit
JumpOrAscendStartCauses the player character to jump (or begins ascent
if swimming or flying)
MoveAndSteerStartBegins moving the player character forward while
steering via mouse movement
MoveAndSteerStopEnds movement initiated by MoveAndSteerStart
MoveBackwardStartBegins moving the player character backward
MoveBackwardStopEnds movement initiated by MoveBackwardStart
MoveForwardStartBegins moving the player character forward
MoveForwardStopEnds movement initiated by MoveForwardStart
PitchDownStartBegins adjusting the player character’s angle of vertical
movement downward
PitchDownStopEnds movement initiated by PitchDownStart
PitchUpStartBegins adjusting the player character’s angle of vertical
movement upward
1080 Part IV Reference
PitchUpStopEnds movement initiated by PitchUpStart
SitStandOrDescendStartCauses the player character to sit down if stand-
ing and vice versa (or begins descent if swimming or flying)
StrafeLeftStartBegins moving the player character sideways to his or
her left
StrafeLeftStopEnds movement initiated by StrafeLeftStart
StrafeRightStartBegins moving the player character sideways to his or
her right
StrafeRightStopEnds movement initiated by StrafeRightStart
ToggleAutoRunStarts or stops the player character automatically moving
forward
ToggleRunSwitches the character’s ground movement mode between run-
ning and walking
TurnLeftStartBegins turning the player character to the left
TurnLeftStopEnds movement initiated by TurnLeftStart
TurnOrActionStartBegins character steering or interaction (equivalent to
right-clicking in the 3-D world)
TurnOrActionStopEnds action initiated by TurnOrActionStart
TurnRightStartBegins turning the player character to the right
TurnRightStopEnds movement initiated by TurnRightStart
Multi-cast Action
SetMultiCastSpellSets a multi-cast action slot to a given spell
NPC ‘‘Gossip’’ Dialog Functions
CloseGossipEnds an NPC ‘‘gossip’’ interaction
GetGossipActiveQuestsReturns a list of quests which can be turned in to
the current Gossip NPC
GetGossipAvailableQuestsReturns a list of quests available from the
current Gossip NPC
GetGossipOptionsReturns a list of interaction options for the Gossip NPC
GetGossipTextReturns greeting or other text to be displayed in an NPC
dialog
Chapter 28 API Categories 1081
GetNumGossipActiveQuestsReturns the number of quests which can be
turned in to the current Gossip NPC
GetNumGossipAvailableQuestsReturns the number of quests available
from the current Gossip NPC
GetNumGossipOptionsReturns the number of non-quest dialog options for
the current Gossip NPC
SelectGossipActiveQuestChooses a quest which can be turned in to the
current Gossip NPC
SelectGossipAvailableQuestChooses a quest available from the current
Gossip NPC
SelectGossipOptionChooses and activates an NPC dialog option
Objectives Tracking Functions
AddQuestWatchAdds a quest to the objectives tracker
AddTrackedAchievementAdds an achievement to the objectives tracker UI
GetNumQuestWatchesReturns the number of quests included in the objec-
tives tracker
GetNumTrackedAchievementsReturns the number of achievements flagged
for display in the objectives tracker UI
GetQuestIndexForWatchReturns the quest log index of a quest in the
objectives tracker
GetQuestLogSpecialItemCooldownReturns cooldown information about
an item associated with a current quest
GetQuestLogSpecialItemInfoReturns information about a usable item
associated with a current quest
GetTrackedAchievementsReturns numeric IDs of the achievements flagged
for display in the objectives tracker UI
IsQuestLogSpecialItemInRangeReturns whether the player’s target is in
range for using an item associated with a current quest
IsQuestWatchedReturns whether a quest from the quest log is listed in the
objectives tracker
IsTrackedAchievementReturns whether an achievement is flagged for
display in the objectives tracker UI
RemoveQuestWatchRemoves a quest from the objectives tracker
RemoveTrackedAchievementRemoves an achievement from the objectives
tracker UI
UseQuestLogSpecialItemUses the item associated with a current quest
1082 Part IV Reference
Party Functions
AcceptGroupAccepts an invitation to join a party or raid
CheckReadyCheckTimeFinishes a ready check initiated by the player
ClearPartyAssignmentRemoves a group role assignment from a member
of the player’s party or raid
ConfirmReadyCheckResponds to a ready check
ConvertToRaidConverts a party to a raid
DeclineGroupDeclines an invitation to join a party or raid
DoReadyCheckInitiates a ready check
GetNumPartyMembersReturns the number of additional members in the
player’s party
GetPartyAssignmentReturns whether a party/raid member is assigned a
specific group role
GetPartyLeaderIndexReturns the index of the current party leader
GetPartyMemberReturns whether a party member exists at a given index
GetReadyCheckStatusReturns a unit’s status during a ready check
GetReadyCheckTimeLeftReturns the amount of time left on the current
ready check
GetRealNumPartyMembersReturns the number of members in the player’s
non-battleground party
InviteUnitInvites a character to the player’s party or raid
IsPartyLeaderReturns whether the player is the party leader
IsRealPartyLeaderReturns whether the player is the leader of a
non-battleground party
LeavePartyExits the current party or raid
PromoteToLeaderPromotes a player to party/raid leader
SetPartyAssignmentAssigns a group role to a member of the player’s
party or raid
UninviteUnitRemoves a character from the player’s party or raid
UnitInPartyReturns whether a unit is a player unit in the player’s party
UnitIsPartyLeaderReturns whether a unit is the leader of the player’s
party
UnitPlayerOrPetInPartyReturns whether a unit is in the player’s party or
belongs to a party member
Chapter 28 API Categories 1083
Pet Stable Functions
BuyStableSlotPurchases the next available stable slot, without confirma-
tion
ClickStablePetInspects or moves a pet in the Pet Stable UI
ClosePetStablesEnds use of the Pet Stable UI/API
GetNextStableSlotCostReturns the cost of the next available stable slot
GetNumStablePetsReturns the number of stabled pets
GetNumStableSlotsReturns the number of stable slots the player has
purchased
GetSelectedStablePetReturns the index of the selected stable pet
GetStablePetFoodTypesReturns the types of food that a stabled pet will
eat
GetStablePetInfoReturns information about a stabled pet
IsAtStableMasterReturns whether the player is interacting with a Stable
Master NPC
PickupStablePetPuts a pet from the stables onto the cursor
SetPetStablePaperdollSets the given Model to show the selected stabled
pet
StablePetPuts the player’s current pet into the stables
UnstablePetMakes a pet from the stables the active pet
Pet Functions
CastPetActionCasts a pet action on a specific target
DestroyTotemDestroys a specific totem (or ghoul)
DisableSpellAutocastDisables automatic casting of a pet spell
EnableSpellAutocastEnables automatic casting of a pet spell
GetPetActionCooldownReturns cooldown information about a given pet
action slot
GetPetActionInfoReturns information about a pet action
GetPetActionSlotUsableReturns whether a pet action can be used
GetPetActionsUsableReturns whether the pet’s actions are usable
GetPetExperienceReturns information about experience points for the
player’s pet
1084 Part IV Reference
GetPetFoodTypesReturns a list of the food types the player’s pet will eat
GetPetHappinessReturns information about the player’s pet’s happiness
GetPetIconReturns an icon representing the current pet
GetPetTalentTreeReturns the name of the talent tree used by the player’s
current pet
GetPetTimeRemainingReturns the time remaining before a temporary pet
is automatically dismissed
GetTotemInfoReturns information on a currently active totem (or ghoul)
GetTotemTimeLeftReturns the time remaining before a totem (or ghoul)
automatically disappears
HasPetSpellsReturns whether the player’s current pet has a spellbook
HasPetUIReturns whether the pet UI should be displayed for the player’s
pet
IsPetAttackActiveReturns whether the pet’s attack action is currently
active
PetAbandonReleases the player’s pet
PetAggressiveModeEnables aggressive mode for the player’s pet
PetAttackInstructs the pet to attack
PetCanBeAbandonedReturns whether the player’s pet can be abandoned
PetCanBeDismissedReturns whether a Dismiss Pet command should be
available for the player’s pet
PetCanBeRenamedReturns whether the player’s pet can be renamed
PetDefensiveModeEnables defensive mode for the player’s pet
PetDismissDismisses the currently controlled pet
PetFollowInstructs the pet to follow the player
PetHasActionBarReturns whether the player’s current pet has an action
bar
PetPassiveModeEnables passive mode for the player’s pet
PetRenameRenames the currently controlled pet
PetStopAttackInstructs the pet to stop attacking
PetWaitInstructs the pet to stay at its current location
PickupPetActionPuts the contents of a pet action slot onto the cursor or
the cursor contents into a pet action slot
TargetTotemTargets one of the player’s totems (or a Death Knight’s ghoul)
TogglePetAutocastTurns autocast on or off for a pet action
Chapter 28 API Categories 1085
Petition Functions
BuyGuildCharterPurchases a guild charter
BuyPetitionPurchases an arena team charter
CanSignPetitionReturns whether the player can sign the currently offered
petition
ClosePetitionEnds interaction with a petition
ClosePetitionVendorEnds interaction with an arena registrar
GetGuildCharterCostReturns the cost to purchase a guild charter
GetNumPetitionNamesReturns the number of people who have signed the
open petition
GetPetitionInfoReturns information about the currently open petition
GetPetitionItemInfoReturns information about a purchasable arena team
charter
GetPetitionNameInfoReturns the name of a character who has signed the
currently offered petition
HasFilledPetitionReturns whether the player has a completed petition
OfferPetitionRequests an arena or guild charter signature from the
targeted unit
RenamePetitionRenames the guild or arena team to be created by the open
petition
SignPetitionSigns the currently offered petition
TurnInArenaPetitionTurns in a petition creating an arena team
TurnInGuildCharterTurns in a completed guild charter
Player Information Functions
AcceptResurrectAccepts an offered resurrection spell
AcceptXPLossResurrects the player as a spirit healer, accepting possible
consequences
CanHearthAndResurrectFromAreaReturns whether the player is in a world
PvP zone offering an exit option
CheckBinderDistReturns whether the player is in range of an NPC that
can set the Hearthstone location
CheckSpiritHealerDistReturns whether the player is in range of a spirit
healer
1086 Part IV Reference
ConfirmBinderSets the player’s Hearthstone to the current location
DeclineResurrectDeclines an offered resurrection spell
DismountDismounts from the player’s summoned mount
GetBindLocationReturns the name of the player’s Hearthstone location
GetComboPointsReturns the player’s number of combo points on the
current target
GetCorpseRecoveryDelayReturns the amount of time left until the player
can recover their corpse
GetCurrentTitleReturns the currently selected player title
GetNumTitlesReturns the number of available player titles
GetPlayerFacingReturns the player’s orientation (heading)
GetQuestLogRewardTitleReturns the title reward for the selected quest in
the quest log
GetRealmNameReturns the name of the player’s realm (server name)
GetReleaseTimeRemainingReturns the amount of time remaining until the
player’s spirit is automatically released when dead
GetResSicknessDurationReturns the duration of resurrection sickness at
the player’s current level
GetRestStateReturns the player’s current rest state
GetRuneCooldownReturns cooldown information about one of the player’s
rune resources
GetRuneCountReturns the number of available rune resources in one of the
player’s rune slots
GetRuneTypeReturns the type of one of the player’s rune resources
GetTitleNameReturns the text of an available player title
GetUnitPitchReturns the player’s current pitch (slope or angle of move-
ment)
GetUnitSpeedReturns a unit’s current speed
GetXPExhaustionReturns the amount of rested bonus experience available
HasFullControlReturns whether the player character can be controlled
HasKeyReturns whether the player has any keys stored in the Keyring
container
HasSoulstoneReturns whether the player can instantly resurrect in place
HasWandEquippedReturns whether the player has a wand equipped
IsFallingReturns whether the player is currently falling
Chapter 28 API Categories 1087
IsFlyableAreaReturns whether flight is allowed on the continent where
the player is currently located
IsFlyingReturns whether the player is currently flying
IsInInstanceReturns whether the player is in an instance (and its type if
applicable)
IsIndoorsReturns whether the player is currently indoors
IsMountedReturns whether the player is mounted
IsOutOfBoundsReturns whether the player is currently outside the bounds
of the world
IsOutdoorsReturns whether the player is currently outdoors
IsRestingReturns whether the player is currently resting
IsStealthedReturns whether the player is currently stealthed
IsSwimmingReturns whether the player is currently swimming
IsTitleKnownReturns whether the player has earned the ability to display
a title
IsXPUserDisabledReturns whether experience gain has been disabled for
the player
OffhandHasWeaponReturns whether the player has an equipped weapon in
the off hand slot
OpeningCinematicDisplays the introductory cinematic for the player’s race
RepopMeReleases the player’s spirit to the nearest graveyard
ResurrectGetOffererReturns the name of a unit offering to resurrect the
player
ResurrectHasSicknessReturns whether accepting an offered resurrection
spell will cause the player to suffer resurrection sickness
ResurrectHasTimerReturns whether the player must wait before resur-
recting
RetrieveCorpseConfirms resurrection by returning to the player’s corpse
SetCurrentTitleChanges a player’s displayed title
ShowCloakEnables or disables display of the player’s cloak
ShowHelmEnables or disables display of the player’s headgear
ShowingCloakReturns whether the player’s cloak is displayed
ShowingHelmReturns whether the player’s headgear is displayed
ToggleSheathSheaths or unsheaths the player character’s hand-held items
1088 Part IV Reference
UnitCharacterPointsReturns the player’s number of unused talent points
and profession slots
UnitXPReturns the player’s current amount of experience points
UnitXPMaxReturns the total amount of experience points required for the
player to gain a level
UseSoulstoneInstantly resurrects the player in place, if possible
PvP Functions
CanHearthAndResurrectFromAreaReturns whether the player is in a world
PvP zone offering an exit option
CanQueueForWintergraspReturns whether the player can queue for Win-
tergrasp
GetHonorCurrencyReturns the player’s amount of honor points
GetNumWorldStateUIReturns the number of world state UI elements
GetPVPDesiredReturns whether the player has manually enabled PvP
status
GetPVPLifetimeStatsReturns the player’s lifetime total of honorable kills
and highest rank achieved
GetPVPRankInfoReturns information about a given PvP rank index
GetPVPSessionStatsReturns the number of kills and honor points scored
by the player since logging in
GetPVPTimerReturns the amount of time until the player’s PVP flag expires
GetPVPYesterdayStatsReturns the number of kills and honor points scored
by the player on the previous day
GetWintergraspWaitTimeReturns the amount of time remaining until the
next PvP event in the Wintergrasp zone
GetWorldPVPQueueStatusReturns information on the players queue for a
world PvP zone
GetWorldStateUIInfoReturns information about a world state UI element
GetZonePVPInfoReturns PVP information about the current area
HearthAndResurrectFromAreaInstantly exits the current world PvP zone,
returning to the player’s Hearthstone location
IsPVPTimerRunningReturns whether the player’s PvP flag will expire after
a period of time
IsSubZonePVPPOIReturns whether the current area has PvP (or other)
objectives to be displayed
Chapter 28 API Categories 1089
QuestFlagsPVPReturns whether accepting the offered quest will flag the
player for PvP
SetPVPEnables or disables the player’s desired PvP status
TogglePVPSwitches the player’s desired PvP status
UnitIsPVPFreeForAllReturns whether a unit is flagged for free-for-all PvP
UnitIsPVPSanctuaryReturns whether a unit is in a Sanctuary area pre-
venting PvP activity
UnitPVPNameReturns the name of a unit including the unit’s current title
Quest Functions
AbandonQuestConfirms abandoning a quest
AcceptQuestAccepts the quest offered by a questgiver
AddQuestWatchAdds a quest to the objectives tracker
CloseQuestEnds interaction with a questgiver
CollapseQuestHeaderCollapses a header in the quest log
CompleteQuestBegins turning in a quest to a questgiver
ConfirmAcceptQuestAccepts a quest started by another group member
DeclineQuestDeclines a quest
ExpandQuestHeaderExpands a quest header in the quest log
GetAbandonQuestItemsReturns information about items that would be
destroyed by abandoning a quest
GetAbandonQuestNameReturns the name of the quest being abandoned
GetActiveLevelReturns the level of a quest which can be turned in to the
current Quest NPC
GetActiveTitleReturns the name of a quest which can be turned in to the
current Quest NPC
GetAvailableLevelReturns the level of a quest available from the current
Quest NPC
GetAvailableTitleReturns the name of a quest available from the current
Quest NPC
GetDailyQuestsCompletedReturns the number of daily quests the player
has completed today
GetGossipActiveQuestsReturns a list of quests which can be turned in to
the current Gossip NPC
1090 Part IV Reference
GetGossipAvailableQuestsReturns a list of quests available from the
current Gossip NPC
GetGreetingTextReturns the greeting text displayed for quest NPCs with
multiple quests
GetMaxDailyQuestsReturns the maximum number of daily quests that can
be completed each day
GetNumActiveQuestsReturns the number of quests which can be turned in
to the current Quest NPC
GetNumAvailableQuestsReturns the number quests available from the
current Quest NPC
GetNumGossipActiveQuestsReturns the number of quests which can be
turned in to the current Gossip NPC
GetNumGossipAvailableQuestsReturns the number of quests available
from the current Gossip NPC
GetNumQuestChoicesReturns the number of available quest rewards from
which the player must choose one upon completing the quest presented
by a questgiver
GetNumQuestItemsReturns the number of different items required to com-
plete the quest presented by a questgiver
GetNumQuestLeaderBoardsReturns the number of quest objectives for a
quest in the player’s quest log
GetNumQuestLogChoicesReturns the number of available item reward
choices for the selected quest in the quest log
GetNumQuestLogEntriesReturns the number of quests and headers in the
quest log
GetNumQuestLogRewardsReturns the number of item rewards for the
selected quest in the quest log
GetNumQuestRewardsReturns the number of different items always
awarded upon completing the quest presented by a questgiver
GetNumQuestWatchesReturns the number of quests included in the objec-
tives tracker
GetNumWorldStateUIReturns the number of world state UI elements
GetObjectiveTextReturns a summary of objectives for the quest offered
by a questgiver
GetProgressTextReturns the quest progress text presented by a questgiver
GetQuestBackgroundMaterialReturns background display style informa-
tion for a questgiver dialog
Chapter 28 API Categories 1091
GetQuestDifficultyColorReturns a table of color values indicating the
difficulty of a quest’s level as compared to the player’s
GetQuestGreenRangeReturns the level range in which a quest below the
player’s level still rewards XP
GetQuestIndexForTimerReturns the quest log index of a timed quest’s
timer
GetQuestIndexForWatchReturns the quest log index of a quest in the
objectives tracker
GetQuestItemInfoReturns information about items in a questgiver dialog
GetQuestItemLinkReturns a hyperlink for an item in a questgiver dialog
GetQuestLinkReturns a hyperlink for an entry in the player’s quest log
GetQuestLogChoiceInfoReturns information about available item rewards
for the selected quest in the quest log
GetQuestLogGroupNumReturns the suggested group size for the selected
quest in the quest log
GetQuestLogItemLinkReturns a hyperlink for an item related to the
selected quest in the quest log
GetQuestLogLeaderBoardReturns information about objectives for a quest
in the quest log
GetQuestLogPushableReturn whether the selected quest in the quest log
canbesharedwithpartymembers
GetQuestLogQuestTextReturns the description and objective text for the
selected quest in the quest log
GetQuestLogRequiredMoneyReturns the amount of money required for the
selected quest in the quest log
GetQuestLogRewardHonorReturns the honor reward for the selected quest
in the quest log
GetQuestLogRewardInfoReturns information about item rewards for the
selected quest in the quest log
GetQuestLogRewardMoneyReturns the money reward for the selected quest
in the quest log
GetQuestLogRewardSpellReturns information about the spell reward for
the selected quest in the quest log
GetQuestLogRewardTalentsReturns the talent point reward for the selected
quest in the quest log
GetQuestLogRewardTitleReturns the title reward for the selected quest in
the quest log
1092 Part IV Reference
GetQuestLogSelectionReturns the index of the selected quest in the
quest log
GetQuestLogSpecialItemCooldownReturns cooldown information about
an item associated with a current quest
GetQuestLogSpecialItemInfoReturns information about a usable item
associated with a current quest
GetQuestLogSpellLinkReturns a hyperlink for a spell in the selected quest
in the quest log
GetQuestLogTimeLeftReturns time remaining for the selected quest in the
quest log
GetQuestLogTitleReturns information about an entry in the player’s quest
log
GetQuestMoneyToGetReturns the amount of money required to complete
the quest presented by a questgiver
GetQuestResetTimeReturns the amount of time remaining until the daily
quest period resets
GetQuestRewardFinishes turning in a quest to a questgiver, selecting an
item reward if applicable
GetQuestSpellLinkReturns a hyperlink for a spell in a questgiver dialog
GetQuestTextReturns the text for the quest offered by a questgiver
GetQuestTimersReturns a list of the times remaining for any active timed
quests
GetRewardHonorReturns the amount of honor points awarded when com-
pleting a quest
GetRewardMoneyReturns the amount of money awarded when completing
aquest
GetRewardSpellReturns information about a spell awarded when com-
pleting a quest
GetRewardTalentsReturns the talent points awarded when completing a
quest
GetRewardTextReturns questgiver dialog to be displayed when completing
aquest
GetRewardTitleReturns the title awarded when completing a quest
GetSuggestedGroupNumReturns the suggested group size for attempting
the quest currently offered by a questgiver
Chapter 28 API Categories 1093
GetTitleTextReturns the title text for the quest presented by a questgiver
GetWorldStateUIInfoReturns information about a world state UI element
IsActiveQuestTrivialReturns whether a quest which can be turned in to
the current Quest NPC is trivial at the player’s level
IsAvailableQuestTrivialReturns whether a quest available from the
current Quest NPC is trivial at the player’s level
IsCurrentQuestFailedReturns whether the player has failed the selected
quest in the quest log
IsQuestCompletableReturns whether the player can complete the quest
presented by a questgiver
IsQuestLogSpecialItemInRangeReturns whether the player’s target is in
range for using an item associated with a current quest
IsQuestWatchedReturns whether a quest from the quest log is listed in the
objectives tracker
IsUnitOnQuestReturns whether a unit is on one of the quests in the player’s
quest log
QuestChooseRewardErrorCauses the default UI to display an error message
indicating that the player must choose a reward to complete the quest
presented by a questgiver
QuestFlagsPVPReturns whether accepting the offered quest will flag the
player for PvP
QuestLogPushQuestShares a quest with other group members
RemoveQuestWatchRemoves a quest from the objectives tracker
SelectActiveQuestSelects a quest which can be turned in to the current
Quest NPC
SelectAvailableQuestChooses a quest available from the current Quest
NPC
SelectGossipActiveQuestChooses a quest which can be turned in to the
current Gossip NPC
SelectGossipAvailableQuestChooses a quest available from the current
Gossip NPC
SelectQuestLogEntrySelects a quest from the quest log
SetAbandonQuestBegins the process of abandoning a quest in the player’s
quest log
UseQuestLogSpecialItemUses the item associated with a current quest
1094 Part IV Reference
Raid Functions
AcceptGroupAccepts an invitation to join a party or raid
CheckReadyCheckTimeFinishes a ready check initiated by the player
ClearPartyAssignmentRemoves a group role assignment from a member
of the player’s party or raid
ConfirmReadyCheckResponds to a ready check
ConvertToRaidConverts a party to a raid
DeclineGroupDeclines an invitation to join a party or raid
DemoteAssistantDemotes the given player from raid assistant status
DoReadyCheckInitiates a ready check
GetNumRaidMembersReturns the number of members in the player’s raid
GetPartyAssignmentReturns whether a party/raid member is assigned a
specific group role
GetRaidRosterInfoReturns information about a member of the player’s
raid
GetRaidRosterSelectionReturns the index of the selected unit in the raid
roster
GetRaidTargetIndexReturns the index of the raid target marker on a unit
GetReadyCheckStatusReturns a unit’s status during a ready check
GetReadyCheckTimeLeftReturns the amount of time left on the current
ready check
GetRealNumRaidMembersReturns the number of members in the player’s
non-battleground raid
InviteUnitInvites a character to the player’s party or raid
IsRaidLeaderReturns whether the player is the raid leader
IsRaidOfficerReturns whether the player is a raid assistant
IsRealRaidLeaderReturns whether the player is the leader of a
non-battleground raid
LeavePartyExits the current party or raid
PromoteToAssistantPromotes a raid member to raid assistant
PromoteToLeaderPromotes a player to party/raid leader
SetPartyAssignmentAssigns a group role to a member of the player’s
party or raid
SetRaidRosterSelectionSelects a unit in the raid roster
SetRaidSubgroupMoves a raid member to a non-full raid subgroup
SetRaidTargetPuts a raid target marker on a unit
Chapter 28 API Categories 1095
SwapRaidSubgroupSwaps two raid members between subgroups in the
raid
UninviteUnitRemoves a character from the player’s party or raid
UnitInRaidReturns whether a unit is in the player’s raid
UnitIsPartyLeaderReturns whether a unit is the leader of the player’s
party
UnitIsRaidOfficerReturns whether a unit is a raid assistant in the player’s
raid
UnitPlayerOrPetInRaidReturns whether a unit is in the player’s raid or
belongs to a raid member
UnitTargetsVehicleInRaidUIReturns whether attempts to target a unit
should target its vehicle
Recruit-a-friend Functions
AcceptLevelGrantAccepts a level offered by the player’s Recruit-a-Friend
partner
CanGrantLevelReturns whether the player can give levels to a Recruit-
a-Friend partner
CanSummonFriendReturns whether a unit can be summoned via Recruit-
a-Friend
DeclineLevelGrantRefuses a level offered by the player’s Recruit-a-Friend
partner
GetSummonFriendCooldownReturns cooldown information about the
player’s Summon Friend ability
GrantLevelGrants a level to the player’s Recruit-a-Friend partner
IsReferAFriendLinkedReturns whether a unit’s account is linked to the
player’s via the Recruit-a-Friend program
SummonFriendSummons a unit whose account is linked to the player’s via
the Recruit-a-Friend program
Secure Execution Utility Functions
InCombatLockdownReturns whether the user interface is protected due to
combat
forceinsecureCauses the current execution path to continue outside the
secure environment
hooksecurefuncAdd a function to be called after execution of a secure
function
1096 Part IV Reference
issecureReturns whether the current execution path is secure
issecurevariableReturns whether a variable is secure (and if not, which
addon tainted it)
newproxyCreates a zero-length userdata with an optional metatable
securecallCalls a function without tainting the execution path
Skill Functions
AbandonSkillUnlearns a skill (used only for professions)
CollapseSkillHeaderCollapses a group header in the Skills UI
ExpandSkillHeaderExpands a group header in the Skills UI
GetNumSkillLinesReturns the number of entries in the Skills UI list
GetSelectedSkillReturns the index of the selected skill in the Skills UI
GetSkillLineInfoReturns information about an entry in the Skills UI list
SetSelectedSkillSelects a skill in the Skills UI
Social Functions
AddFriendAdds a character to the friends list
AddIgnoreAdds a character to the ignore list
AddOrDelIgnoreAdds the named character to the ignore list, or removes
the character if already in the ignore list
AddOrRemoveFriendAdds the named character to the friends list, or
removes the character if already in the friends list
DelIgnoreRemoves a player from the ignore list
GetFriendInfoReturns information about a character on the player’s
friends list
GetIgnoreNameReturns the name of a character on the ignore list
GetNumFriendsReturns the number of characters on the player’s friends
list
GetNumIgnoresReturns the number of characters on the player’s ignore list
GetNumWhoResultsReturns the number of results from a Who system query
GetSelectedFriendReturns the index of the selected character in the
player’s friends list
Chapter 28 API Categories 1097
GetSelectedIgnoreReturns the index of the selected character in the
player’s ignore list
GetWhoInfoReturns information about a character in the Who system query
results
IsIgnoredReturns whether a unit is on the player’s ignore list
RemoveFriendRemoves a character from the friends list
SendWhoRequests a list of characters meeting given search criteria from the
server
SetFriendNotesSets note text associated with a friends list entry
SetSelectedFriendSelects a character in the player’s friends list
SetSelectedIgnoreSelects a character in the player’s ignore list
SetWhoToUIChanges the delivery method for results from SendWho()
queries
ShowFriendsRequests friends/ignore list information from the server
SortWhoSorts the Who system query results list
Socketing Functions
AcceptSocketsAccepts changes made in the Item Socketing UI
ClickSocketButtonPicks up or places a gem in the Item Socketing UI
CloseSocketInfoEnds interaction with the Item Socketing UI, discarding
any changes made
GetExistingSocketInfoReturns information about a permanently sock-
eted gem
GetExistingSocketLinkReturns a hyperlink for a permanently socketed
gem
GetItemGemReturns information about gems socketed in an item
GetNewSocketInfoReturns information about a gem added to a socket
GetNewSocketLinkReturns a hyperlink for a gem added to a socket
GetNumSocketsReturns the number of sockets on the item currently being
socketed
GetSocketItemBoundTradeableReturns whether the item open for socket-
ing is temporarily tradeable
GetSocketItemInfoReturns information about the item currently being
socketed
1098 Part IV Reference
GetSocketItemRefundableReturns whether the item open for socketing is
temporarily refundable
GetSocketTypesReturns information about the gem types usable in a socket
SocketContainerItemOpens an item from the player’s bags for socketing
SocketInventoryItemOpens an equipped item for socketing
Sound Functions
PlayMusicPlays an audio file as background music
PlaySoundPlays one of WoW’s built-in sound effects
PlaySoundFilePlays an audio file at a given path
Sound_ChatSystem_GetInputDriverNameByIndexReturns the name of the
given chat system sound input driver
Sound_ChatSystem_GetNumInputDriversReturns the number of chat sys-
tem sound input drivers
Sound_ChatSystem_GetNumOutputDriversReturns the number of chat sys-
tem sound output drivers
Sound_ChatSystem_GetOutputDriverNameByIndexReturns the name of the
given chat system sound output driver
Sound_GameSystem_GetInputDriverNameByIndexReturns the name of the
given game sound input driver
Sound_GameSystem_GetNumInputDriversReturns the number of game
sound input drivers
Sound_GameSystem_GetNumOutputDriversReturns the number of game
sound output drivers
Sound_GameSystem_GetOutputDriverNameByIndexReturns the name of the
given game sound output driver
Sound_GameSystem_RestartSoundSystemRestarts the game’s sound sys-
tems
StopMusicStops currently playing in-game music
VoiceEnumerateCaptureDevicesReturns the name of an audio input device
for voice chat
VoiceEnumerateOutputDevicesReturns the name of an audio output
device for voice chat
VoiceGetCurrentCaptureDeviceReturns the index of the current voice
capture device
Chapter 28 API Categories 1099
VoiceGetCurrentOutputDeviceReturns the index of the current voice out-
put device
VoiceSelectCaptureDeviceSelects an audio input device for voice chat
VoiceSelectOutputDeviceSelects an audio output device for voice chat
Spell Functions
CastSpellCasts a spell from the spellbook
CastSpellByIDCasts a spell specified by ID (optionally on a specified unit)
CastSpellByNameCasts a spell specified by name (optionally on a specified
unit)
CursorHasSpellReturns whether a spell is on the cursor
DisableSpellAutocastDisables automatic casting of a pet spell
EnableSpellAutocastEnables automatic casting of a pet spell
GetItemSpellReturns information about the spell cast by an item’s ‘‘Use:’’
effect
GetKnownSlotFromHighestRankSlotReturns the spellbook slot for the pla-
yer’s highest known rank of a spell
GetNumSpellTabsReturns the number of tabs in the player’s spellbook
GetQuestLogRewardSpellReturns information about the spell reward for
the selected quest in the quest log
GetRewardSpellReturns information about a spell awarded when com-
pleting a quest
GetSpellAutocastReturns information about automatic casting for a spell
in the spellbook
GetSpellCooldownReturns cooldown information about a spell in the spell-
book
GetSpellCountReturns the number of times a spell can be cast
GetSpellInfoReturns information about a spell
GetSpellLinkReturns a hyperlink for a spell
GetSpellNameReturns the name and secondary text for a spell in the
spellbook
GetSpellTabInfoReturns information about a tab in the spellbook
GetSpellTextureReturns the icon texture path for a spell
HasPetSpellsReturns whether the player’s current pet has a spellbook
1100 Part IV Reference
IsAttackSpellReturns whether a spell is the standard melee Attack spell
IsAutoRepeatSpellReturns whether a spell is an automatically repeating
spell
IsConsumableSpellReturns whether casting a spell consumes a reagent
item
IsCurrentSpellReturns whether a spell is currently being used
IsHarmfulSpellReturns whether a spell can be used against hostile units
IsHelpfulSpellReturns whether an item can be used on the player or
friendly units
IsPassiveSpellReturns whether a spell is passive (cannot be cast)
IsSelectedSpellReturns whether a spell is currently selected in the spell-
book
IsSpellInRangeReturns whether the player is in range to cast a spell on a
unit
IsSpellKnownReturns whether the player (or pet) knows a spell
IsUsableSpellReturns whether or not a given spell is usable or cannot be
used due to lack of mana
PickupSpellPuts a spell from the player’s or pet’s spellbook onto the
cursor
SetMultiCastSpellSets a multi-cast action slot to a given spell
SpellCanTargetGlyphReturns whether the spell currently awaiting a target
requires a glyph slot to be chosen
SpellCanTargetItemReturns whether the spell currently awaiting a target
requires an item to be chosen
SpellCanTargetUnitReturns whether the spell currently awaiting a target
can target a given unit
SpellHasRangeReturns whether an item has a range limitation for its use
SpellIsTargetingReturns whether a spell is currently awaiting a target
SpellStopCastingStops casting or targeting the spell in progress
SpellStopTargetingCancels the spell currently awaiting a target
SpellTargetItemCasts the spell currently awaiting a target on an item
SpellTargetUnitCasts the spell currently awaiting a target on a unit
ToggleSpellAutocastEnables or disables automatic casting of a spell
UnitCastingInfoReturns information about the spell a unit is currently
casting
Chapter 28 API Categories 1101
UnitChannelInfoReturns information about the spell a unit is currently
channeling
UpdateSpellsRequests spellbook information from the server
Stance/Shapeshift Functions
CancelShapeshiftFormCancels the current shapeshift form
CastShapeshiftFormCasts an ability on the stance/shapeshift bar
GetNumShapeshiftFormsReturns the number of abilities to be presented on
the stance/shapeshift bar
GetShapeshiftFormReturns the index of the active ability on the stance/
shapeshift bar
GetShapeshiftFormCooldownReturns cooldown information about an
ability on the stance/shapeshift bar
GetShapeshiftFormInfoReturns information about an ability on the
stance/shapeshift bar
Stat Information Functions
GetArmorPenetrationReturns the percentage of enemy armor ignored due
to the player’s Armor Penetration Rating
GetAttackPowerForStatReturns the attack power bonus provided by one
of the player’s basic statistics
GetBlockChanceReturns the player’s percentage chance to block with a
shield
GetCombatRatingReturns the value of a combat rating for the player
GetCombatRatingBonusReturns the percentage effect for the player’s cur-
rent value of a given combat rating
GetCritChanceReturns the player’s melee critical strike chance
GetCritChanceFromAgilityReturns additional critical strike chance pro-
vided by Agility
GetDamageBonusStatReturns the index of the basic statistic that provides
increased physical damage
GetDodgeChanceReturns the player’s chance to dodge melee attacks
GetExpertiseReturns the player’s current expertise value
GetExpertisePercentReturns the reduction in chance to be dodged or
parried conferred by the player’s expertise value
1102 Part IV Reference
GetManaRegenReturns information about the player’s mana regeneration
rate
GetMaxCombatRatingBonusReturns the maximum possible percentage
bonus for a given combat rating
GetParryChanceReturns the player’s parry chance
GetPowerRegenReturns information about the player’s mana/energy/etc.
regeneration rate
GetRangedCritChanceReturns the player’s ranged critical strike chance
GetShieldBlockReturns the amount of damage prevented when the player
blocks with a shield
GetSpellBonusDamageReturns the player’s spell damage bonus for a spell
school
GetSpellBonusHealingReturns the player’s amount of bonus healing
GetSpellCritChanceReturns the player’s spell critical strike chance for a
spell school
GetSpellCritChanceFromIntellectReturns additional spell critical strike
chance provided by Intellect
GetSpellPenetrationReturns the amount of enemy magic resistance
ignored due to the player’s Spell Penetration Rating
GetUnitHealthModifierReturns the health modifier for the player’s pet
GetUnitHealthRegenRateFromSpiritReturns the increase in health regen-
eration rate provided by Spirit
GetUnitManaRegenRateFromSpiritReturns the increase in mana regenera-
tion rate provided by Spirit
GetUnitMaxHealthModifierReturns the maximum health modifier for the
player’s pet
GetUnitPowerModifierReturns the mana modifier for the player’s pet
UnitArmorReturns the player’s or pet’s armor value
UnitAttackBothHandsReturns information about the player’s or pet’s
weapon skill
UnitAttackPowerReturns the player’s or pet’s melee attack power
UnitAttackSpeedReturns information about the player’s or pet’s melee
attack speed
UnitDamageReturns information about the player’s or pet’s melee attack
damage
UnitDefenseReturns the player’s or pet’s Defense skill
Chapter 28 API Categories 1103
UnitRangedAttackReturns information about the player’s or pet’s ranged
weapon skill
UnitRangedAttackPowerReturns the player’s or pet’s ranged attack power
UnitRangedDamageReturns information about the player’s or pet’s ranged
attack damage and speed
UnitResistanceReturns information about the player’s or pet’s magic
resistance
UnitStatReturns information about a basic character statistic for the player
or pet
Summoning Functions
CancelSummonDeclines an offered summons
ConfirmSummonAccepts an offered summons, teleporting the player to the
summoner’s location
GetSummonConfirmAreaNameReturns the destination area of an offered sum-
mons
GetSummonConfirmSummonerReturns the name of the unit offering a sum-
mons to the player
GetSummonConfirmTimeLeftReturns the amount of time remaining before
an offered summons expires
PlayerCanTeleportReturns whether the player can accept a summons
Talent Functions
AddPreviewTalentPointsSpends (or unspends) talent points in the Talent
UI’s preview mode
CheckTalentMasterDistReturns whether the player is in range of an NPC
that can reset talents
ConfirmTalentWipeResets the player’s talents
GetActiveTalentGroupReturns the index of the active talent specialization
GetGroupPreviewTalentPointsSpentReturns the total number of points
spent in the Talent UI’s preview mode
GetNumTalentGroupsReturns the number of talent specs a character can
switch among
GetNumTalentTabsReturns the number of talent tabs for the player, pet, or
inspect target
1104 Part IV Reference
GetNumTalentsReturns the number of options in a talent tab
GetPetTalentTreeReturns the name of the talent tree used by the player’s
current pet
GetTalentInfoReturns information about a talent option
GetTalentLinkReturns a hyperlink for a talent
GetTalentPrereqsReturns information about prerequisites to learning a
talent
GetTalentTabInfoReturns information about a talent tab
GetUnspentTalentPointsReturns the number of unused talent points
LearnPreviewTalentsCommits changes made in the Talent UI’s preview
mode
LearnTalentLearns a talent, spending one talent point
ResetGroupPreviewTalentPointsReverts all changes made in the Talent
UI’s preview mode
ResetPreviewTalentPointsReverts changes made within a specific tab in
the Talent UI’s preview mode
SetActiveTalentGroupSwitches the player’s active talent specialization
UnitCharacterPointsReturns the player’s number of unused talent points
and profession slots
Targeting Functions
AssistUnitTargets the unit targeted by another unit
ClearFocusClears the player’s focus unit
ClearTargetClears the player’s current target
FocusUnitChanges the focus unitID to refer to a new unit
SpellCanTargetUnitReturns whether the spell currently awaiting a target
can target a given unit
SpellTargetUnitCasts the spell currently awaiting a target on a unit
TargetLastEnemyTargets the most recently targeted enemy unit
TargetLastFriendTargets the most recently targeted friendly unit
TargetLastTargetTargets the most recently targeted unit
TargetNearestCycles targets through nearest units regardless of reac-
tion/affiliation
TargetNearestEnemyCycles your target through the nearest enemy units
TargetNearestEnemyPlayerCycles targets through nearby enemy player
units
TargetNearestFriendCycles targets through nearby friendly units
Chapter 28 API Categories 1105
TargetNearestFriendPlayerCycles targets through nearby friendly player
units
TargetNearestPartyMemberCycles targets through nearby party members
TargetNearestRaidMemberCycles targets through nearby raid members
TargetUnitTargets a unit
Taxi/Flight Functions
CloseTaxiMapEnds interaction with the Taxi (flight master) UI
GetNumRoutesReturns the number of hops from the current location to
another taxi node
GetTaxiBenchmarkModeReturns whether flight path benchmark mode is
enabled
NumTaxiNodesReturns the number of flight points on the taxi map
SetTaxiBenchmarkModeEnables or disables flight path benchmark mode
SetTaxiMapSets a Texture object to show the appropriate flight map texture
TakeTaxiNodeEmbarks on a taxi flight to a given destination
TaxiGetDestXReturns the horizontal coordinate of a taxi flight’s destination
node
TaxiGetDestYReturns the vertical coordinate of a taxi flight’s destination
node
TaxiGetSrcXReturns the horizontal coordinate of a taxi flight’s source node
TaxiGetSrcYReturns the vertical coordinate of a taxi flight’s source node
TaxiNodeCostReturns the cost to fly to a given taxi node
TaxiNodeGetTypeReturns the type of a flight point
TaxiNodeNameReturns the name of a flight point
TaxiNodePositionReturns the position of a flight point on the taxi map
TaxiNodeSetCurrentSets the ‘‘current’’ flight path node
UnitOnTaxiReturns whether a unit is currently riding a flight path (taxi)
Threat Functions
GetThreatStatusColorReturns color values for a given threat status
IsThreatWarningEnabledReturns whether the default Aggro Warning UI
should currently be shown
UnitDetailedThreatSituationReturns detailed information about the
threat status of one unit against another
UnitThreatSituationReturns the general threat status of a unit
1106 Part IV Reference
Tracking Functions
GetNumTrackingTypesReturns the number of available minimap object/
unit tracking abilities
GetTrackingInfoReturns information about a given tracking option
GetTrackingTextureReturns the texture of the active tracking ability
SetTrackingEnables a given minimap object/unit tracking ability
Trade Functions
AcceptTradeAccepts a proposed trade
AddTradeMoneyAdds the money currently on the cursor to the trade win-
dow
CancelTradeCancels a trade in progress
CancelTradeAcceptCancels the player’s acceptance of a trade
ClickTargetTradeButtonInteracts with an item in a slot offered for trade
by the target
ClickTradeButtonPicksupanitemfromorputsaniteminaslotoffered
for trade by the player
CloseTradeEnds interaction with the Trade UI, canceling any trade in
progress
GetPlayerTradeMoneyReturns the amount of money offered for trade by
the player
GetTargetTradeMoneyReturns the amount of money offered for trade by
the target
GetTradePlayerItemInfoReturns information about an item offered for
trade by the player
GetTradePlayerItemLinkReturns a hyperlink for an item offered for trade
by the player
GetTradeTargetItemInfoReturns information about an item offered for
trade by the target
GetTradeTargetItemLinkReturns a hyperlink for an item offered for trade
by the target
InitiateTradeOffers to trade with a given unit
PickupTradeMoneyPuts money offered by the player for trade onto the
cursor
Chapter 28 API Categories 1107
ReplaceTradeEnchantConfirms replacement of an existing enchantment
when offering an enchantment for trade
SetTradeMoneyOffers an amount of money for trade
Trade Skill Functions
CloseTradeSkillEnds interaction with the Trade Skill UI
CollapseTradeSkillSubClassCollapses a group header in the trade skill
listing
DoTradeSkillPerforms a trade skill recipe
ExpandTradeSkillSubClassExpands a group header in the trade skill
listing
GetFirstTradeSkillReturns the index of the first non-header in the trade
skill listing
GetNumTradeSkillsReturns the number of entries in the trade skill listing
GetTradeSkillCooldownReturns the time remaining on a trade skill recipe’s
cooldown
GetTradeSkillDescriptionReturns descriptive text for a tradeskill recipe
GetTradeSkillIconReturns the icon for a trade skill recipe
GetTradeSkillInfoReturns information about a trades kill header or recipe
GetTradeSkillInvSlotFilterReturns whether the trade skill listing is
filtered by a given item equipment slot
GetTradeSkillInvSlotsReturns a list of recipe equipment slots for the
current trade skill
GetTradeSkillItemLevelFilterReturns the current settings for filtering
the trade skill listing by required level of items produced
GetTradeSkillItemLinkReturns a hyperlink for the item created by a trade
skill recipe
GetTradeSkillItemNameFilterReturns the current search text for filtering
the trade skill listing by name
GetTradeSkillLineReturns information about the current trade skill
GetTradeSkillListLinkReturns a hyperlink to the player’s list of recipes
for the current trade skill
GetTradeSkillNumMadeReturns the number of items created when per-
forming a trade skill recipe
GetTradeSkillNumReagentsReturns the number of different reagents
required for a trade skill recipe
1108 Part IV Reference
GetTradeSkillReagentInfoReturns information about a reagent in a trade
skill recipe
GetTradeSkillReagentItemLinkReturns a hyperlink for a reagent in a
trade skill recipe
GetTradeSkillRecipeLinkReturns a hyperlink for a trade skill recipe
GetTradeSkillSelectionIndexReturns the index of the currently selected
trade skill recipe
GetTradeSkillSubClassFilterReturns whether the trade skill listing is
filtered by a given item subclass
GetTradeSkillSubClassesReturns a list of recipe subclasses for the current
trade skill
GetTradeSkillToolsReturns a list of required tools for a trade skill recipe
GetTradeskillRepeatCountReturns the number of times the trade skill
recipe currently being performed will repeat
IsTradeSkillLinkedReturns whether the Trade Skill UI is showing another
player’s skill
SelectTradeSkillSelects a recipe in the trade skill listing
SetTradeSkillInvSlotFilterFilters the trade skill listing by equipment
slot of items produced
SetTradeSkillItemLevelFilterFilters the trade skill listing by required
level of items produced
SetTradeSkillItemNameFilterFilters the trade skill listing by name of
recipe, item produced, or reagents
SetTradeSkillSubClassFilterFilters the trade skill listing by subclass of
items produced
StopTradeSkillRepeatCancels repetition of a trade skill recipe
TradeSkillOnlyShowMakeableFilters the trade skill listing by whether the
player currently has enough reagents for each recipe
TradeSkillOnlyShowSkillUpsFilters the trade skill listing by whether the
player can gain skill ranks from each recipe
Trainer Functions
BuyTrainerServicePurchases an ability or recipe available from a trainer
CheckTalentMasterDistReturns whether the player is in range of an NPC
that can reset talents
Chapter 28 API Categories 1109
CloseTrainerEnds interaction with a trainer
CollapseTrainerSkillLineCollapses a group header in the trainer service
listing
ExpandTrainerSkillLineExpands a group header in the trainer service
listing
GetNumTrainerServicesReturns the number of entries in the trainer service
listing
GetTrainerGreetingTextReturns the current trainer’s greeting text
GetTrainerSelectionIndexReturns the index of the currently selected
trainer service
GetTrainerServiceAbilityReqReturns information about an ability
required for purchasing a trainer service
GetTrainerServiceCostReturns the cost to purchase a trainer service
GetTrainerServiceDescriptionReturns the description of a trainer service
GetTrainerServiceIconReturns the icon for a trainer service
GetTrainerServiceInfoReturns information about an entry in the trainer
service listing
GetTrainerServiceItemLinkReturns a hyperlink for the item associated
with a trainer service
GetTrainerServiceLevelReqReturns the character level required to pur-
chase a trainer service
GetTrainerServiceNumAbilityReqReturns the number of ability require-
ments for purchasing a trainer service
GetTrainerServiceSkillLineReturns the name of the skill line associated
with a trainer service
GetTrainerServiceSkillReqReturns information about the skill require-
ment for a trainer service
GetTrainerServiceTypeFilterReturns whether the trainer service listing
is filtered by a service status
GetTrainerSkillLineFilterReturns whether the trainer service listing is
filtered by a skill line
GetTrainerSkillLinesReturns the list of service group names available at
atrainer
IsTradeSkillTrainerReturns whether the player is interacting with a
trade skill trainer (as opposed to a class trainer)
1110 Part IV Reference
IsTrainerServiceSkillStepReturns whether a trainer service is a trade
skill level
SelectTrainerServiceSelects an entry in the trainer service listing
SetTrainerServiceTypeFilterFilters the trainer service listing by service
status
SetTrainerSkillLineFilterFilters the trainer service listing by skill line
UnitCharacterPointsReturns the player’s number of unused talent points
and profession slots
Tutorial Functions
ClearTutorialsDisables contextual tutorial display
FlagTutorialMarks a contextual tutorial as displayed so it doesn’t appear
again
ResetTutorialsEnables contextual tutorial display and clears the list of
already displayed tutorials
TutorialsEnabledReturns whether contextual tutorials are enabled
UI/Visual Functions
ConsoleAddMessagePrints text to the debug console
ConsoleExecRuns a console command
SetupFullscreenScaleSizes a frame to take up the entire screen regardless
of screen resolution
ShowCloakEnables or disables display of the player’s cloak
ShowHelmEnables or disables display of the player’s headgear
ShowingCloakReturns whether the player’s cloak is displayed
ShowingHelmReturns whether the player’s headgear is displayed
Unit Functions
CanInspectReturns whether a unit can be inspected
CheckInteractDistanceReturns whether the player is close enough to a
unit for certain types of interaction
GetGuildInfoReturns a unit’s guild affiliation
GetMuteStatusReturns whether a character is muted or silenced
Chapter 28 API Categories 1111
GetPlayerInfoByGUIDReturns information about a player character iden-
tified by globally unique identifier
GetUnitNameReturns a string summarizing a unit’s name and server
GetUnitSpeedReturns a unit’s current speed
IsIgnoredOrMutedReturns whether a unit can be heard due to
ignored/muted status
IsMutedReturns whether a character has been muted by the player
IsUnitOnQuestReturns whether a unit is on one of the quests in the player’s
quest log
SetPortraitTextureSets a Texture object to show a portrait of a unit
UnitAffectingCombatReturns whether a unit is currently in combat
UnitAuraReturns information about buffs/debuffs on a unit
UnitBuffReturns information about a buff on a unit
UnitCanAssistReturns whether one unit can assist another
UnitCanAttackReturns whether one unit can attack another
UnitCanCooperateReturns whether two units can cooperate
UnitCastingInfoReturns information about the spell a unit is currently
casting
UnitChannelInfoReturns information about the spell a unit is currently
channeling
UnitClassReturns a unit’s class
UnitClassBaseReturns a unit’s class
UnitClassificationReturns a unit’s classification
UnitCreatureFamilyReturns the creature family of the unit
UnitCreatureTypeReturns the creature type of a unit
UnitDebuffReturns information about a debuff on a unit
UnitExistsReturns whether a unit exists
UnitFactionGroupReturns a unit’s primary faction allegiance
UnitGUIDReturns a unit’s globally unique identifier
UnitHasRelicSlotReturns whether a unit has a relic slot instead of a
ranged weapon slot
UnitHealthReturns a unit’s current amount of health
UnitHealthMaxReturns a unit’s maximum health value
1112 Part IV Reference
UnitInBattlegroundReturns whether a unit is in the same battleground
instance as the player
UnitInPartyReturns whether a unit is a player unit in the player’s party
UnitInRaidReturns whether a unit is in the player’s raid
UnitInRangeReturns whether a party/raid member is nearby
UnitIsAFKReturns whether a unit is marked AFK (Away From Keyboard)
UnitIsCharmedReturns whether a unit is currently charmed
UnitIsConnectedReturns whether a unit is connected (i.e. not Offline)
UnitIsControllingReturns whether a unit is controlling another unit
UnitIsCorpseReturns whether a unit is a corpse
UnitIsDNDReturns whether a unit is marked DND (Do Not Disturb)
UnitIsDeadReturns whether a unit is dead
UnitIsDeadOrGhostReturns whether a unit is either dead or a ghost
UnitIsEnemyReturns whether two units are enemies
UnitIsFeignDeathReturns whether a unit is feigning death
UnitIsFriendReturns whether two units are friendly
UnitIsGhostReturns whether a unit is currently a ghost
UnitIsInMyGuildReturns whether a unit is in the player’s guild
UnitIsPVPReturns whether a unit is flagged for PvP activity
UnitIsPVPFreeForAllReturns whether a unit is flagged for free-for-all PvP
UnitIsPVPSanctuaryReturns whether a unit is in a Sanctuary area pre-
venting PvP activity
UnitIsPartyLeaderReturns whether a unit is the leader of the player’s
party
UnitIsPlayerReturns whether a unit is a player unit (not an NPC)
UnitIsPossessedReturns whether a unit is possessed by another
UnitIsRaidOfficerReturns whether a unit is a raid assistant in the player’s
raid
UnitIsSameServerReturns whether two units are from the same server
UnitIsTappedReturns whether a unit is tapped
UnitIsTappedByAllThreatListReturns whether a unit allows all players
on its threat list to receive kill credit
UnitIsTappedByPlayerReturns whether a unit is tapped by the player or
the player’s group
Chapter 28 API Categories 1113
UnitIsTrivialReturns whether a unit is trivial at the player’s level
UnitIsUnitReturns whether two unit references are to the same unit
UnitIsVisibleReturns whether a unit is in the player’s area of interest
UnitLevelReturns a unit’s level
UnitNameReturns the name of a unit
UnitOnTaxiReturns whether a unit is currently riding a flight path (taxi)
UnitPVPNameReturns the name of a unit including the unit’s current title
UnitPlayerControlledReturns whether a unit is controlled by a player
UnitPlayerOrPetInPartyReturns whether a unit is in the player’s party or
belongs to a party member
UnitPlayerOrPetInRaidReturns whether a unit is in the player’s raid or
belongs to a raid member
UnitPowerReturns a unit’s current level of mana, rage, energy or other
power type
UnitPowerMaxReturns a unit’s maximum mana, rage, energy or other
power type
UnitPowerTypeReturns the power type (energy, mana, rage) of the given
unit
UnitRaceReturns the name of a unit’s race
UnitReactionReturns the reaction of one unit with regards to another as a
number
UnitSelectionColorReturns a color indicating hostility and related status
of a unit
UnitSexReturns the gender of the given unit or player
UnitUsingVehicleReturns whether a unit is using a vehicle
Utility Functions
CreateFontCreates a new Font object
CreateFrameCreates a new Frame object
EnumerateFramesReturns the next frame following the frame passed, or
nil if no more frames exist
GetAutoCompleteResultsReturns a list of character names which complete
a given partial name prefix
GetClickFrameReturns the Frame object associated with the given name
1114 Part IV Reference
GetCurrentKeyBoardFocusReturns the frame currently handling keyboard
input
GetFramesRegisteredForEventReturns all frames registered for a given
event
GetMirrorTimerInfoReturns information about special countdown timers
GetMirrorTimerProgressReturns a high-resolution value for a special
countdown timer
GetMouseButtonClickedReturns which mouse button triggered the current
script
GetMouseButtonNameReturns the name for a mouse button specified by
number
GetMouseFocusReturns the frame that is currently under the mouse, and
has mouse input enabled
GetMuteNameReturns the name of a character on the mute list
GetNumFramesReturns the number of existing Frame objects (and deriva-
tives)
GetTextReturns a localized string according to given parameters
GetTimeReturns a number representing the current time (with millisecond
precision)
IsLoggedInReturns whether the login process has completed
IsMouseButtonDownReturns whether a given mouse button is held down
RequestTimePlayedRequests information from the server about the player
character’s total time spent online
RunScriptRuns a string as a Lua script
SecondsToTimeReturns a description of an amount of time in appropriate
units
SetPortraitToTextureSets a Texture object to display an arbitrary texture,
altering it to fit a circular frame
debuglocalsReturns information about the local variables at a given stack
depth
getglobalReturns the value of a global variable
scrubReplaces non-simple values in a list with nil
setglobalSets a global variable to a specified value
strconcatJoins a list of strings (with no separator)
strjoinJoins a list of strings together with a given separator
Chapter 28 API Categories 1115
strlenutf8Returns the length of a string, taking UTF-8 multi-byte charac-
ters into account
strreplaceFast simple substring substitution
strsplitSplits a string based on another separator string
strtrimTrims leading and trailing characters (whitespace by default) from
astring
wipeRemoves all entries from a table
Vehicle Functions
CanEjectPassengerFromSeatReturns whether the player can eject the occu-
pant of a seat in the player’s vehicle
CanExitVehicleReturns whether the player is in a vehicle
CanSwitchVehicleSeatReturns whether the player can change vehicle
seats
CanSwitchVehicleSeatsReturns whether the player is in a vehicle with
multiple seats
CombatTextSetActiveUnitSets the main unit for display of floating combat
text
EjectPassengerFromSeatEjects the occupant of a seat in the player’s
vehicle
IsVehicleAimAngleAdjustableReturns whether the player is controlling a
vehicle weapon with adjustable aim angle
UnitControllingVehicleReturns whether a unit is controlling a vehicle
UnitHasVehicleUIReturns whether a unit is controlling a vehicle or vehicle
weapon
UnitInVehicleReturns whether a unit is in a vehicle
UnitInVehicleControlSeatReturns whether a unit controls a vehicle
UnitIsControllingReturns whether a unit is controlling another unit
UnitSwitchToVehicleSeatMoves the player to another seat within his
current vehicle
UnitTargetsVehicleInRaidUIReturns whether attempts to target a unit
should target its vehicle
UnitUsingVehicleReturns whether a unit is using a vehicle
UnitVehicleSeatCountReturns the number of seats in a unit’s vehicle
UnitVehicleSeatInfoReturns information about seats in a vehicle
UnitVehicleSkinReturns the style of vehicle UI to display for a unit
1116 Part IV Reference
VehicleAimDecrementAdjusts vehicle aim downward by a specified
amount
VehicleAimDownStartStarts adjusting vehicle aim downward
VehicleAimDownStopStops adjusting vehicle aim downward
VehicleAimGetAngleReturns the aim angle of a vehicle weapon
VehicleAimGetNormAngleReturns the aim angle of a vehicle weapon rela-
tive to its minimum angle
VehicleAimIncrementAdjusts vehicle aim upward by a specified amount
VehicleAimRequestAngleAttempts to set a vehicle weapon’s aim angle to
aspecicvalue
VehicleAimRequestNormAngleAttempts to set a vehicle weapon’s aim
angle to a specific value relative to its minimum value
VehicleAimUpStartStarts adjusting vehicle aim upward
VehicleAimUpStopStops adjusting vehicle aim upward
VehicleCameraZoomInZooms the player’s view in while in a vehicle
VehicleCameraZoomOutZooms the player’s view out while in a vehicle
VehicleExitRemoves the player from the current vehicle
VehicleNextSeatMoves the player from his current seat in a vehicle to the
next sequentially numbered seat
VehiclePrevSeatMoves the player from his current seat in a vehicle to the
previous sequentially numbered seat
Video Functions
GetCurrentMultisampleFormatReturns the index of the current multisam-
ple setting
GetCurrentResolutionReturns the index of the current resolution setting
GetFramerateReturns the number of frames per second rendered by the
client
GetGammaReturns the current display gamma setting
GetMultisampleFormatsReturns a list of available multisample settings
GetRefreshRatesReturns a list of available screen refresh rates
GetScreenHeightReturns the height of the screen for UI layout purposes
GetScreenResolutionsReturns a list of available screen resolutions
GetScreenWidthReturns the width of the screen for UI layout purposes
Chapter 28 API Categories 1117
GetTerrainMipReturns the level of terrain detail displayed
GetVideoCapsReturns information about graphics capabilities of the cur-
rent system
IsDesaturateSupportedReturns whether the current hardware supports
desaturated textures
IsPlayerResolutionAvailableReturns whether the current hardware
supports high resolution player textures
IsStereoVideoAvailableReturns whether the current system supports
stereoscopic 3D display
RestartGxRestart the client’s graphic subsystem
RestoreVideoEffectsDefaultsResets video effects options to default val-
ues
RestoreVideoResolutionDefaultsResets video resolution options to
default values
RestoreVideoStereoDefaultsResets stereoscopic 3D video options to
default values
SetGammaChanges the display gamma setting
SetMultisampleFormatChanges the multisample setting
SetScreenResolutionChanges the screen resolution
SetTerrainMipChanges the level of terrain detail displayed
Voice Functions
AddMuteAdds a character to the muted list for voice chat
AddOrDelMuteAdds or removes a character from the voice mute list
ChannelSilenceAllSilences a character for chat and voice on a channel
ChannelSilenceVoiceSilences the given character for voice chat on the
channel
ChannelUnSilenceAllUnsilences a character for chat and voice on a
channel
ChannelUnSilenceVoiceUnsilences a character on a chat channel
ChannelVoiceOffDisables voice chat in a channel
ChannelVoiceOnEnables voice chat in a channel
DelMuteRemoves a character from the muted list for voice chat
DisplayChannelVoiceOffDisables voice in a channel specified by its posi-
tion in the channel list display
1118 Part IV Reference
DisplayChannelVoiceOnEnables voice in a channel specified by its position
in the channel list display
GetActiveVoiceChannelReturns the currently active voice channel
GetMuteNameReturns the name of a character on the mute list
GetMuteStatusReturns whether a character is muted or silenced
GetNumMutesReturns the number of characters on the player’s mute list
GetNumVoiceSessionMembersBySessionIDReturns the number of members
in a voice channel
GetNumVoiceSessionsReturns the number of available voice channels
GetSelectedMuteReturns the index of the selected entry in the Muted list
GetVoiceCurrentSessionIDReturns an identifier for the active voice ses-
sion
GetVoiceSessionInfoReturns information about a voice session
GetVoiceSessionMemberInfoBySessionIDReturns information about a
member of a voice channel
GetVoiceStatusReturns whether a character has voice chat enabled
IsIgnoredOrMutedReturns whether a unit can be heard due to
ignored/muted status
IsMutedReturns whether a character has been muted by the player
IsSilencedReturns whether a character is silenced on a chat channel
IsVoiceChatAllowedReturns whether the player is allowed to enable the
voice chat feature
IsVoiceChatAllowedByServerReturns whether voice chat is supported by
the realm server
IsVoiceChatEnabledReturns whether the voice chat system is enabled
SetActiveVoiceChannelSets the currently active voice channel
SetActiveVoiceChannelBySessionIDSets the currently active voice chat
channel
SetSelectedMuteSelects an entry in the Muted list
UnitIsSilencedReturns whether a character is silenced on a voice channel
UnitIsTalkingReturns whether a unit is currently speaking in voice chat
VoiceChat_GetCurrentMicrophoneSignalLevelReturns the current vol-
ume level of the microphone signal
VoiceChat_IsPlayingLoopbackSoundReturns whether the Microphone
Test recording is playing
Chapter 28 API Categories 1119
VoiceChat_IsRecordingLoopbackSoundReturns whether a Microphone
Test is recording
VoiceChat_PlayLoopbackSoundPlays back the Microphone Test recording
VoiceChat_RecordLoopbackSoundBegins recording a Microphone Test
VoiceChat_StopPlayingLoopbackSoundStops playing the Microphone Test
recording
VoiceChat_StopRecordingLoopbackSoundStops recording a Microphone
Test
VoiceEnumerateCaptureDevicesReturns the name of an audio input device
for voice chat
VoiceEnumerateOutputDevicesReturns the name of an audio output
device for voice chat
VoiceGetCurrentCaptureDeviceReturns the index of the current voice
capture device
VoiceGetCurrentOutputDeviceReturns the index of the current voice out-
put device
VoiceIsDisabledByClientReturns whether the voice chat system cannot
be enabled
VoiceSelectCaptureDeviceSelects an audio input device for voice chat
VoiceSelectOutputDeviceSelects an audio output device for voice chat
Zone Information Functions
GetMinimapZoneTextReturns the name of the current area (as displayed in
the Minimap)
GetRealZoneTextReturns the ‘‘official’’ name of the zone or instance in
which the player is located
GetSubZoneTextReturns the name of the minor area in which the player is
located
GetZonePVPInfoReturns PvP information about the current area
GetZoneTextReturns the name of the zone in which the player is located
IsSubZonePVPPOIReturns whether the current area has PvP (or other)
objectives to be displayed
CHAPTER
29
Widget Reference
To respond to game events or interact with the user in any way, an addon must make
use of game widgets. This chapter provides a reference for the various widget types
that exist in World of Warcraft, along with the script handlers that can be used for
interaction with the user.
Widget Types
There are more 25 different widget types available in the WoW user interface. This
section details these types along with the abstract types that are used to clarify the
hierarchy and inheritance of the various widget methods.
UIObject
UIObject is an abstract UI object type that is used to group together methods that are
common to all user interface types. All of the various user interface elements in World
of Warcraft are derived from UIObject.
UIObject defines the following methods:
GetName
Returns the widget object’s name.
name = UIObject:GetName()
Returns:
name—Name of the object (string)
GetObjectType
Returns the object’s widget type.
type = UIObject:GetObjectType()
1121
1122 Part IV Reference
Returns:
type—Name of the objects type (e.g. Frame,Button,FontString,etc)
(string)
IsObjectType
Returns whether the object belongs to a given widget type.
isType = UIObject:IsObjectType(“type“)
Arguments:
typeName of an object type (e.g. Frame,Button,FontString,etc)(string)
Returns:
isType1if the object belongs to the given type (or a subtype thereof); other-
wise nil (1nil)
ParentedObject
ParentedObject is an abstract UI type that provides support for querying the parent
of a given object. Some object parents are set implicitly (such as in the case of font
strings and textures) whereas others are set explicitly using the SetParent() method
provided by the Region object type.
ParentedObject has all the methods from UIObject, plus the following:
GetParent
Returns the object’s parent object.
parent = ParentedObject:GetParent()
Returns:
parentReference to the object’s parent object, or nil if the object has no par-
ent (uiobject)
ScriptObject
ScriptObject is an abstract UI type that provides support for scripts, such as OnLoad,
OnEvent and OnFinished. Scripts can be set to trigger in response to some widget
event, or as a result of user interaction. The specific scripts that are supported vary
wildly from object to object, but all objects support setting, hooking and getting of
object scripts.
UIObject defines the following methods:
GetScript
Returns the widget’s handler function for a script.
handler = ScriptObject:GetScript(“scriptType“)
Arguments:
scriptTypeA script type; see scripts reference for details (string)
Returns:
handlerThe object’s handler function for the script type (function)
Chapter 29 Widget Reference 1123
HasScript
Returns whether the widget supports a script handler.
hasScript = ScriptObject:HasScript(“scriptType“)
Arguments:
scriptTypeA script type; see scripts reference for details (string)
Returns:
hasScript1if the widget can handle the script, otherwise nil (1nil)
HookScript
Securely hooks a script handler.
ScriptObject:HookScript(“scriptType“, handler)
Equivalent to hooksecurefunc() for script handlers; allows one to
‘‘post-hook’’ a secure handler without tainting the original.
The original handler will still be called, but the handler supplied will also be
called after the original, with the same arguments. Return values from the
supplied handler are discarded. Note that there is no API to remove a hook
from a handler: any hooks applied will remain in place until the UI is reloaded.
If there was no prior script handler set, then this simply sets the new function
as the handler for the script type.
Arguments:
scriptTypeName of the script whose handler should be hooked (string)
handlerA function to be called whenever the script handler is run
(function)
Example:
-- hooks the default UI’s player frame to insert a chat link to the
-- player’s most recently completed achievement when shift-clicked
function PlayerLink(self, button, down)
if ( IsModifiedClick(“CHATLINK“) ) then
local link = i
GetAchievementLink(select(1,GetLatestCompletedAchievements()))
ChatEdit_InsertLink (link)
end
end
PlayerFrame:HookScript(“OnClick“, PlayerLink)
SetScript
Sets the widget’s handler function for a script.
ScriptObject:SetScript(“scriptType“, handler)
Arguments:
scriptTypeA script type; see scripts for details (string)
handlerA function to become the widget’s handler for the script type
(function)
1124 Part IV Reference
Region
Region is the basic type for anything that can occupy an area of the screen. As such,
Frames, Textures and FontStrings are all various kinds of Region. Region provides
most of the functions that support size, position and anchoring, including animation.
It is a ‘‘real virtual’’ type; it cannot be instantiated, but objects can return true when
asked if they are Regions.
Region has all the methods from ParentedObject, plus the following:
CanChangeProtectedState
Returns whether protected properties of the region can be changed by
non-secure scripts.
canChange = Region:CanChangeProtectedState()
Addon scripts are allowed to change protected properties for non-secure
frames, or for secure frames while the player is not in combat.
Returns:
canChange1if addon scripts are currently allowed to change pro-
tected properties of the region (e.g. showing or hiding it, changing its
position, or altering frame attributes); otherwise nil (value, 1nil)
ClearAllPoints
Removes all anchor points from the region.
Region:ClearAllPoints()
CreateAnimationGroup
Creates a new AnimationGroup as a child of the region.
animationGroup =i
Region:CreateAnimationGroup([“name“ [, “inheritsFrom“]])
Arguments:
name (optional)A global name to use for the new animation group (string)
inheritsFrom (optional)Template from which the new animation group
should inherit (string)
Returns:
animationGroupThe newly created AnimationGroup (animgroup)
GetAnimationGroups
Returns a list of animation groups belonging to the region.
... = Region:GetAnimationGroups()
Returns:
...A list of AnimationGroup objects for which the region is parent (list)
GetBottom
Returns the distance from the bottom of the screen to the bottom of the region.
bottom = Region:GetBottom()
Chapter 29 Widget Reference 1125
Returns:
bottomDistance from the bottom edge of the screen to the bottom edge of the
region (in pixels) (number)
GetCenter
Returns the screen coordinates of the region’s center.
x, y = Region:GetCenter()
Returns:
xDistance from the left edge of the screen to the center of the region (in pixels)
(number)
yDistance from the bottom edge of the screen to the center of the region (in
pixels) (number)
GetHeight
Returns the height of the region.
height = Region:GetHeight()
Returns:
heightHeight of the region (in pixels) (number)
GetLeft
Returns the distance from the left edge of the screen to the left edge of the
region.
left = Region:GetLeft()
Returns:
leftDistance from the left edge of the screen to the left edge of the region (in
pixels) (number)
GetNumPoints
Returns the number of anchor points defined for the region.
numPoints = Region:GetNumPoints()
Returns:
numPointsNumber of defined anchor points for the region (number)
GetPoint
Returns information about one of the region’s anchor points.
point, relativeTo, relativePoint, xOffset, yOffset = i
Region:GetPoint(index)
Arguments:
indexIndex of an anchor point defined for the region (between 1and
region:GetNumPoints())(number)
Returns:
pointPoint on this region at which it is anchored to another (string, anchor-
Point)
1126 Part IV Reference
relativeToReference to the other region to which this region is anchored
(region)
relativePointPoint on the other region to which this region is anchored
(string, anchorPoint)
xOffsetHorizontal distance between point and relativePoint (in pix-
els; positive values put point to the right of relativePoint)(number)
yOffsetVertical distance between point and relativePoint (in
pixels; positive values put point below relativePoint)(number)
GetRect
Returns the position and dimensions of the region.
left, bottom, width, height = Region:GetRect()
Returns:
leftDistance from the left edge of the screen to the left edge of the region (in
pixels) (number)
bottomDistance from the bottom edge of the screen to the bottom of the
region (in pixels) (number)
widthWidth of the region (in pixels) (number)
heightHeight of the region (in pixels) (number)
GetRight
Returns the distance from the left edge of the screen to the right edge of the
region.
right = Region:GetRight()
Returns:
rightDistance from the left edge of the screen to the right edge of the region
(in pixels) (number)
GetTop
Returns the distance from the bottom of the screen to the top of the region.
top = Region:GetTop()
Returns:
topDistance from the bottom edge of the screen to the top edge of the region
(in pixels) (number)
GetWidth
Returns the width of the region.
width = Region:GetWidth()
Returns:
widthWidth of the region (in pixels) (number)
IsDragging
Returns whether the region is currently being dragged.
isDragging = Region:IsDragging()
Chapter 29 Widget Reference 1127
Returns:
isDragging1if the region (or its parent or ancestor) is currently being
dragged; otherwise nil (1nil)
IsProtected
Returns whether the region is protected.
isProtected, explicit = Region:IsProtected()
Non-secure scripts may change certain properties of a protected region (e.g.
showing or hiding it, changing its position, or altering frame attributes) only
while the player is not in combat. Regions may be explicitly protected by
Blizzard scripts or XML; other regions can become protected by becoming
children of protected regions or by being positioned relative to protected
regions.
Returns:
isProtected1if the region is protected; otherwise nil (value, 1nil)
explicit1if the region is explicitly protected; nil if the frame is only
protected due to relationship with a protected region (value, 1nil)
SetAllPoints
Sets all anchor points of the region to match those of another region.
Region:SetAllPoints([region]) or Region:SetAllPoints([“name“])
If no region is specified, the region’s anchor points are set to those of its parent.
Arguments:
region (optional)Reference to a region (region)
name (optional)Global name of a region (string)
SetHeight
Sets the region’s height.
Region:SetHeight(height)
Arguments:
heightNew height for the region (in pixels); if 0, causes the region’s height
to be determined automatically according to its anchor points (number)
SetParent
Makes another frame the parent of this region.
Region:SetParent(frame) or Region:SetParent(“name“)
Arguments:
frameThe new parent frame (frame)
nameGlobal name of a frame (string)
SetPoint
Sets an anchor point for the region.
Region:SetPoint(“point“ [, relativeTo [, “relativePoint“ i
[, xOffset [, yOffset]]]])
1128 Part IV Reference
Arguments:
pointPoint on this region at which it is to be anchored to another (string,
anchorPoint)
relativeTo (optional)Reference to the other region to which this region
is to be anchored; if nil or omitted, anchors the region relative to its parent
(or to the screen dimensions if the region has no parent) (region)
relativePoint (optional)Point on the other region to which this region is
to be anchored; if nil or omitted, defaults to the same value as point (string,
anchorPoint)
xOffset (optional)Horizontal distance between point and relativePoint
(in pixels; positive values put point to the right of relativePoint); if nil or
omitted, defaults to 0(number)
yOffset (optional)Vertical distance between point and relativePoint (in
pixels; positive values put point below relativePoint); if nil or omitted,
defaults to 0(number)
Example:
-- Create a sample frame and give it a visible background color
local frame = CreateFrame(“Frame“, “TestFrame“, UIParent)
local background = i
frame:CreateTexture(“TestFrameBackground“, “BACKGROUND“)
background:SetTexture(1, 1, 1, 0.25)
background:SetAllPoints()
-- Set the top left corner 5px to the right and 15px above UIParent’s
-- top left corner
frame:SetPoint(“TOPLEFT“, 5, 15)
-- Set the bottom edge to be 10px below WorldFrame’s center
frame:SetPoint(“BOTTOM“, WorldFrame, “CENTER“, 0, -10)
-- Set the right edge to be 20px to the left of WorldFrame’s right edge
frame:SetPoint(“RIGHT“, WorldFrame, -20, 0)
SetWidth
Sets the region’s width.
Region:SetWidth(width)
Arguments:
widthNew width for the region (in pixels); if 0, causes the region’s width
to be determined automatically according to its anchor points (number)
StopAnimating
Stops any active animations involving the region or its children.
Region:StopAnimating()
Chapter 29 Widget Reference 1129
VisibleRegion
VisibleRegion is an abstract UI type used to describe the common functionality of
objects that can be placed on the screen, and visible. In particular, methods exist to
show and hide the frame, and change the alpha transparency.
VisibleRegion has all the methods from Region, plus the following:
GetAlpha
Returns the opacity of the region relative to its parent.
alpha = VisibleRegion:GetAlpha()
Returns:
alphaAlpha (opacity) of the region (0.0 =fully transparent, 1.0 =fully
opaque) (number)
Hide
Hides the region.
VisibleRegion:Hide()
IsShown
Returns whether the region is shown.
shown = VisibleRegion:IsShown()
Indicates only whether the region has been explicitly shown or hiddena
region may be explicitly shown but not appear on screen because its parent
region is hidden. See VisibleRegion:IsVisible() to test for actual
visibility.
Returns:
shown1if the region is shown; otherwise nil (1nil)
IsVisible
Returns whether the region is visible.
visible = VisibleRegion:IsVisible()
A region is ‘‘visible’’ if it has been explicitly shown (or not explicitly hidden)
and its parent is visible (that is, all of its ancestor frames (parent, parent’s
parent, etc) are also shown).
A region may be ‘‘visible’’ and not appear on screenit may not have any
anchor points set, its position and size may be outside the bounds of the screen,
or it may not draw anything (e.g. a FontString with no text, a Texture with no
image, or a Frame with no visible children).
Returns:
visible1if the region is visible; otherwise nil (1nil)
SetAlpha
Sets the opacity of the region relative to its parent.
VisibleRegion:SetAlpha(alpha)
1130 Part IV Reference
Arguments:
alphaAlpha (opacity) of the region (0.0 =fully transparent, 1.0 =fully
opaque) (number)
Show
Shows the region.
VisibleRegion:Show()
LayeredRegion
LayeredRegion is an abstract UI type that groups together the functionality of layered
graphical regions, specifically Textures and FontStrings. These objects can be moved
from one layer to another, or can be suppressed by turning off the layer on the frame
to which they are attached. These layered regions can also be colorized in the graphics
engine using the :SetVertexColor() method.
LayeredRegion has all the methods from VisibleRegion, plus the following:
GetDrawLayer
Returns the layer at which the region’s graphics are drawn relative to others in
its frame.
layer = LayeredRegion:GetDrawLayer()
Returns:
layerString identifying a graphics layer; one of the following values:
(string,layer)
ARTWORK
BACKGROUND
BORDER
HIGHLIGHT
OVERLAY
SetDrawLayer
Sets the layer at which the region’s graphics are drawn relative to others in its
frame.
LayeredRegion:SetDrawLayer(“layer“)
Arguments:
layerString identifying a graphics layer; one of the following values:
(string,layer)
ARTWORK
BACKGROUND
BORDER
HIGHLIGHT
OVERLAY
SetVertexColor
Sets a color shading for the region’s graphics.
LayeredRegion:SetVertexColor(red, green, blue [, alpha])
Chapter 29 Widget Reference 1131
The effect of changing this property differs by the type of region:
For FontStrings, this color overrides the normal text color (as set by
FontInstance:SetTextColor()).
For Textures, this color acts as a filter applied to the texture image: each color
component value is a factor by which the corresponding component values in
the image are multiplied. (See examples.)
Arguments:
redRed component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
blueBlue component of the color (0.0 - 1.0) (number)
alpha (optional)Alpha (opacity) for the graphic (0.0 =fully transparent, 1.0 =
fully opaque) (number)
Example:
-- first, target an elite creature or NPC so the “gold dragon“ target
-- border appears then try running the following scripts:
TargetFrameTexture:SetVertexColor(1,0,0)
-- omits the green and blue channels from the image, giving it
-- a red tint
TargetFrameTexture:SetVertexColor(0,0,1)
-- omits the red and green channels from the image: note the image
-- is mostly black because the gold color of the dragon image comes
-- primarily from red and green channels
TargetFrameTexture:SetVertexColor(0,0,0)
-- omits all color channels, leaving a black shadow defined by
-- the image’s alpha channel
TargetFrameTexture:SetVertexColor(1,1,1)
-- removes vertex shading, returning the image to its original colors
FontInstance
FontInstance is an abstract UI type that groups together the functionality of text-based
frames, such as Buttons, MessageFrames, EditBoxes, SimpleHTML frames and abstract
Font objects. Methods are provided for setting text color and changing other aspects
of font display like typeface, size, justification, shadow and spacing.
FontInstance has all the methods from UIObject, plus the following:
GetFont
Returns the font instance’s basic font properties.
filename, fontHeight, flags = FontInstance:GetFont()
Returns:
filename—Path to a font file (string)
1132 Part IV Reference
fontHeightHeight (point size) of the font to be displayed (in pixels) (number)
flagsAdditional properties for the font specified by one or more (separated
by commas) of the following tokens: (string)
MONOCHROME - Font is rendered without anti-aliasing
OUTLINE - Font is displayed with a black outline
THICKOUTLINE - Font is displayed with a thick black outline
GetFontObject
Returns the Font object from which the font instance’s properties are inherited.
font = FontInstance:GetFontObject()
See FontInstance:SetFontObject() for details.
Returns:
fontReference to the Font object from which the font instance’s properties
are inherited, or nil if the font instance has no inherited properties (font)
GetJustifyH
Returns the font instance’s horizontal text alignment style.
justify = FontInstance:GetJustifyH()
Returns:
justifyHorizontal text alignment style (string,justifyH)
CENTER
LEFT
RIGHT
GetJustifyV
Returns the font instance’s vertical text alignment style.
justify = FontInstance:GetJustifyV()
Returns:
justifyVertical text alignment style (string,justifyV)
BOTTOM
MIDDLE
TOP
GetShadowColor
Returns the color of the font’s text shadow.
shadowR, shadowG, shadowB, shadowAlpha = FontInstance:GetShadowColor()
Returns:
shadowRRed component of the shadow color (0.0 - 1.0) (number)
shadowGGreen component of the shadow color (0.0 - 1.0) (number)
shadowBBlue component of the shadow color (0.0 - 1.0) (number)
Chapter 29 Widget Reference 1133
shadowAlphaAlpha (opacity) of the text’s shadow (0.0 =fully transparent, 1.0
=fully opaque) (number)
GetShadowOffset
Returns the offset of the font instance’s text shadow from its text.
xOffset, yOffset = FontInstance:GetShadowOffset()
Returns:
xOffsetHorizontal distance between the text and its shadow (in pixels)
(number)
yOffsetVertical distance between the text and its shadow (in pixels)
(number)
GetSpacing
Returns the font instance’s amount of spacing between lines.
spacing = FontInstance:GetSpacing()
Returns:
spacingAmount of space between lines of text (in pixels) (number)
GetTextColor
Returns the font instance’s default text color.
textR, textG, textB, textAlpha = FontInstance:GetTextColor()
Returns:
textRRed component of the text color (0.0 - 1.0) (number)
textGGreen component of the text color (0.0 - 1.0) (number)
textBBlue component of the text color (0.0 - 1.0) (number)
textAlphaAlpha(opacity)ofthetext(0.0=fully transparent, 1.0 =fully
opaque) (number)
SetFont
Sets the font instance’s basic font properties.
isValid = FontInstance:SetFont(“filename“, fontHeight, “flags“)
Font files included with the default WoW client:
Fonts\\FRIZQT__.TTF - Friz Quadrata, used by default for player names
and most UI text
Fonts\\ARIALN.TTF - Arial Narrow, used by default for chat windows,
action button numbers, etc
Fonts\\skurri.ttf - Skurri, used by default for incoming dam-
age/parry/miss/etc indicators on the Player and Pet frames
Fonts\\MORPHEUS.ttf - Morpheus, used by default for quest title headers,
mail and readable in-game objects.
Font files can also be included in addons.
Arguments:
filename—Path to a font file (string)
1134 Part IV Reference
fontHeightHeight (point size) of the font to be displayed (in pixels) (number)
flagsAdditional properties for the font specified by one or more (separated
by commas) of the following tokens: (string)
MONOCHROME - Font is rendered without anti-aliasing
OUTLINE - Font is displayed with a black outline
THICKOUTLINE - Font is displayed with a thick black outline
Returns:
isValid1if filename refers to a valid font file; otherwise nil (1nil)
SetFontObject
Sets the Font object from which the font instance’s properties are inherited.
FontInstance:SetFontObject(object) or FontInstance:SetFontObject
(“name“)
This method allows for easy standardization and reuse of font styles. For
example, a button’s normal font can be set to appear in the same style as many
default UI elements by setting its font to “GameFontNormal“if Blizzard
changes the main UI font in a future path, or if the user installs another addon
which changes the main UI font, the button’s font will automatically change
to match.
Arguments:
objectReference to a Font object (font)
name—Global name of a Font object (string)
SetJustifyH
Sets the font instance’s horizontal text alignment style.
FontInstance:SetJustifyH(“justify“)
Arguments:
justifyHorizontal text alignment style (string,justifyH)
CENTER
LEFT
RIGHT
SetJustifyV
Sets the font instance’s horizontal text alignment style.
FontInstance:SetJustifyV(“justify“)
Arguments:
justifyVertical text alignment style (string,justifyV)
BOTTOM
MIDDLE
TOP
SetShadowColor
Sets the color of the font’s text shadow.
FontInstance:SetShadowColor(shadowR, shadowG, shadowB, shadowAlpha)
Chapter 29 Widget Reference 1135
Arguments:
shadowRRed component of the shadow color (0.0 - 1.0) (number)
shadowGGreen component of the shadow color (0.0 - 1.0) (number)
shadowBBlue component of the shadow color (0.0 - 1.0) (number)
shadowAlphaAlpha (opacity) of the text’s shadow (0.0 =fully transparent, 1.0
=fully opaque) (number)
SetShadowOffset
Sets the offset of the font instance’s text shadow from its text.
FontInstance:SetShadowOffset(xOffset, yOffset)
Arguments:
xOffsetHorizontal distance between the text and its shadow (in pixels)
(number)
yOffsetVertical distance between the text and its shadow (in pixels)
(number)
Example:
-- Moves the text shadow in the default text font further than normal
-- from the text (5 pixels right and 5 pixels down instead of
-- 1 pixel right and 1 pixel down)
ChatFontNormal:SetShadowOffset(5,-5)
SetSpacing
Sets the font instance’s amount of spacing between lines.
FontInstance:SetSpacing(spacing)
Arguments:
spacingAmount of space between lines of text (in pixels) (number)
SetTextColor
Sets the font instance’s default text color.
FontInstance:SetTextColor(textR, textG, textB, textAlpha)
This color is used for otherwise unformatted text displayed using the font
instance; however, portions of the text may be colored differently using the
colorString format (commonly seen in hyperlinks).
Arguments:
textRRed component of the text color (0.0 - 1.0) (number)
textGGreen component of the text color (0.0 - 1.0) (number)
textBBlue component of the text color (0.0 - 1.0) (number)
textAlphaAlpha(opacity)ofthetext(0.0=fully transparent, 1.0 =fully
opaque) (number)
FontString
FontStrings are one of the two types of Region that is visible on the screen. It draws a
block of text on the screen using the characteristics in an associated FontObject. You
1136 Part IV Reference
can change the text contents of it, set it to use a new FontObject, and set how it handles
text that doesn’t fit in its normal dimensions, such as how to wrap the text and whether
to indent subsequent lines.
FontStrings are used widely through the UI, to display labels on controls, the names
of units, keybindings on action buttons, health and mana values and most other text
data.
FontString has all the methods from Region, VisibleRegion, LayeredRegion and
FontInstance, plus the following:
CanNonSpaceWrap
Returns whether long lines of text will wrap within or between words.
enabled = FontString:CanNonSpaceWrap()
Returns:
enabled1if long lines of text will wrap at any character boundary (i.e possi-
bly in the middle of a word); nil to only wrap at whitespace characters (i.e. only
between words) (1nil)
CanWordWrap
Returns whether long lines of text in the font string can wrap onto subsequent
lines.
enabled = FontString:CanWordWrap()
Returns:
enabled1if long lines of text can wrap onto subsequent lines; otherwise nil
(1nil)
GetMultilineIndent
Returns whether long lines of text are indented when wrapping.
enabled = FontString:GetMultilineIndent()
Returns:
enabled1if long lines of text are indented when wrapping; otherwise nil
(1nil)
GetStringHeight
Returns the height of the text displayed in the font string.
height = FontString:GetStringHeight()
This value is based on the text currently displayed; e.g. a long block of text
wrapped to several lines results in a greater height than that for a short block
of text that fits on fewer lines.
Returns:
heightHeight of the text currently displayed in the font string (in pixels)
(number)
GetStringWidth
Returns the width of the text displayed in the font string.
width = FontString:GetStringWidth()
Chapter 29 Widget Reference 1137
This value is based on the text currently displayed; e.g. a short text label results
in a smaller width than a longer block of text. Very long blocks of text that don’t
fit the font string’s dimensions all result in similar widths, because this method
measures the width of the text displayed, which is truncated with an ellipsis
(‘‘...’’).
Returns:
widthWidth of the text currently displayed in the font string
(in pixels) (number)
GetText
Returns the text currently set for display in the font string.
text = FontString:GetText()
This is not necessarily the text actually displayed: text that does not fit within
the FontString’s dimensions will be truncated with an ellipsis (‘‘...’’) for
display.
Returns:
textText to be displayed in the font string (string)
SetAlphaGradient
Creates an opacity gradient over the text in the font string.
FontString:SetAlphaGradient(start, length)
Seen in the default UI when quest text is presented by a questgiver (if the
‘‘Instant Quest Text’’ feature is not turned on): This method is used with a
length of 30 to fade in the letters of the description, starting at the first
character; then the start value is incremented in an OnUpdate script, creating
the animated fade-in effect.
Arguments:
startCharacter position in the font string’s text at which the gradient should
begin (between 0and string.len(fontString:GetText()) - 6)(number)
lengthWidth of the gradient in pixels, or 0to restore the text to full opacity
(number)
SetFormattedText
Sets the text displayed in the font string using format specifiers.
FontString:SetFormattedText(“formatString“, ...)
Equivalent to :SetText(format(format, ...)),butdoesnotcreatea
throwaway Lua string object, resulting in greater memory-usage efficiency.
Arguments:
formatStringA string containing format specifiers (as with
string.format())(string)
...A list of values to be included in the formatted string (list)
SetMultilineIndent
Sets whether long lines of text are indented when wrapping.
FontString:SetMultilineIndent(enable)
1138 Part IV Reference
Arguments:
enableTrue to indent wrapped lines of text; false otherwise (boolean)
SetNonSpaceWrap
Sets whether long lines of text will wrap within or between words.
FontString:SetNonSpaceWrap(enable)
Arguments:
enableTrue to wrap long lines of text at any character bound-
ary (i.e possibly in the middle of a word); false to only wrap at
whitespace characters (i.e. only between words) (boolean)
SetText
Sets the text to be displayed in the font string.
FontString:SetText(“text“)
Arguments:
textText to be displayed in the font string (string)
SetTextHeight
Scales the font string’s rendered text to a different height.
FontString:SetTextHeight(height)
This method scales the image of the text as already rendered at its existing
height by the game’s graphics engineproducing an effect which is efficient
enough for use in fast animations, but with reduced visual quality in the text.
To re-render the text at a new point size, see :SetFont().
Arguments:
heightHeight (point size) to which the text should be scaled (in pixels)
(number)
SetWordWrap
Sets whether long lines of text in the font string can wrap onto subsequent
lines.
FontString:SetWordWrap(enable)
Arguments:
enableTrue to allow long lines of text in the font string to wrap onto subse-
quent lines; false to disallow (boolean)
Texture
Textures are visible areas descended from LayeredRegion, that display either a color
block, a gradient, or a graphic raster taken from a .tga or .blp file. Most of their methods
relate to setting their appearance or their source information.
Textures are created as children of Frame elements in XML, or by calling
Frame:CreateTexture() from Lua. They cannot be reassigned from one frame to
another, although you can create another texture on another frame that has the same
source. They can also be created in XML with the virtual tag, allowing several similar
textures to be created easily.
Chapter 29 Widget Reference 1139
Texture has all the methods from Region, VisibleRegion and LayeredRegion, plus
the following:
GetBlendMode
Returns the blend mode of the texture.
mode = Texture:GetBlendMode()
Returns:
modeBlend mode of the texture (string)
ADD - Adds texture color values to the underlying color values, using the
alpha channel; light areas in the texture lighten the background while dark
areas are more transparent
ALPHAKEY - One-bit transparency; pixels with alpha values greater than 0.8
are treated as fully opaque and all other pixels are treated as fully transparent
BLEND - Normal color blending, using any alpha channel in the texture image
DISABLE - Ignores any alpha channel, displaying the texture as fully opaque
MOD - Ignores any alpha channel in the texture and multiplies texture
color values by background color values; dark areas in the texture
darken the background while light areas are more transparent
GetNonBlocking
Returns whether the texture object loads its image file in the background.
nonBlocking = Texture:GetNonBlocking()
See :SetNonBlocking() for further details.
Returns:
nonBlocking1if the texture object loads its image file in the background;
nil if the game engine is halted while the texture loads (1nil)
GetTexCoord
Returns corner coordinates for scaling or cropping the texture image.
ULx, ULy, LLx, LLy, URx, URy, LRx, LRy = Texture:GetTexCoord()
See Texture:SetTexCoord() example for details.
Returns:
ULxUpper left corner X position, as a fraction of the image’s width from the
left (number)
ULyUpper left corner Y position, as a fraction of the image’s height from the
top (number)
LLxLower left corner X position, as a fraction of the image’s width from the
left (number)
LLyLower left corner Y position, as a fraction of the image’s height from the
top (number)
URxUpper right corner X position, as a fraction of the image’s width from the
left (number)
URyUpper right corner Y position, as a fraction of the image’s height from the
top (number)
1140 Part IV Reference
LRxLower right corner X position, as a fraction of the image’s width from the
left (number)
LRyLower right corner Y position, as a fraction of the image’s height from the
top (number)
GetTexCoordModifiesRect
Sets whether modifying texture coordinates scales or crops the texture image.
modifiesRect = Texture:GetTexCoordModifiesRect()
See Texture:SetTexCoordModifiesRect() example for details.
Returns:
modifiesRectTrue if future Texture:SetTexCoord() operations will crop
the texture image; false if SetTexCoord will scale the image (boolean)
GetTexture
Returns the path to the texture’s image file.
texture = Texture:GetTexture()
Returns:
texturePath to the texture image file, or one of the following values:
(string)
Portrait1 - Texture is set to a generated image (e.g. via SetPortrait
Texture())
SolidTexture - Texture is set to a solid color instead of an image
GetVertexColor
Returns the shading color of the texture.
red, green, blue, alpha = Texture:GetVertexColor()
For details about vertex color shading, see LayeredRegion:
SetVertexColor().
Returns:
redRed component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
blueBlue component of the color (0.0 - 1.0) (number)
alphaAlpha (opacity) for the texture (0.0 =fully transparent, 1.0 =fully
opaque) (number)
IsDesaturated
Returns whether the texture image should be displayed with zero saturation
(i.e. converted to grayscale).
desaturated = Texture:IsDesaturated()
The texture may not actually be displayed in grayscale if the current display
hardware doesn’t support that feature; see Texture:SetDesaturated() for
details.
Returns:
desaturated1if the texture should be displayed in grayscale; otherwise nil
(1nil)
Chapter 29 Widget Reference 1141
SetBlendMode
Sets the blend mode of the texture.
Texture:SetBlendMode(“mode“)
Arguments:
modeBlend mode of the texture (string)
ADD - Adds texture color values to the underlying color values, using the
alpha channel; light areas in the texture lighten the background while dark
areas are more transparent
ALPHAKEY - One-bit transparency; pixels with alpha values greater than 0.8
are treated as fully opaque and all other pixels are treated as fully transparent
BLEND - Normal color blending, using any alpha channel in the texture image
DISABLE - Ignores any alpha channel, displaying the texture as fully opaque
MOD - Ignores any alpha channel in the texture and multiplies texture
color values by background color values; dark areas in the texture
darken the background while light areas are more transparent
SetDesaturated
Sets whether the texture image should be displayed with zero saturation (i.e.
converted to grayscale).
supported = Texture:SetDesaturated(desaturate)
Returns nil if the current system does not support texture desaturation; in
such cases, this method has no visible effect (but still flags the texture object as
desaturated). Authors may wish to implement an alternative to desaturation
for such cases (see example).
Arguments:
desaturateTrue to display the texture in grayscale; false to display origi-
nal texture colors (boolean)
Returns:
supported1if the current system supports texture desaturation; otherwise
nil (1nil)
Example:
-- Wrapper for the desaturation feature used in the default UI: if
-- running on display hardware (or drivers, etc) that does not support
-- desaturation, uses SetVertexColor to “dim“ the texture instead
function SetDesaturation(texture, desaturation)
local shaderSupported = texture:SetDesaturated(desaturation);
if ( not shaderSupported ) then
if ( desaturation ) then
texture:SetVertexColor(0.5, 0.5, 0.5);
else
texture:SetVertexColor(1.0, 1.0, 1.0);
end
end
end
1142 Part IV Reference
SetGradient
Sets a gradient color shading for the texture.
Texture:SetGradient(“orientation“, startR, startG, startB, endR,i
endG, endB)
Gradient color shading does not change the underlying color of the texture
image, but acts as a filter: see LayeredRegion:SetVertexColor() for details.
Arguments:
orientationToken identifying the direction of the gradient (string)
HORIZONTAL - Start color on the left, end color on the right
VERTICAL - Start color at the bottom, end color at the top
startRRed component of the start color (0.0 - 1.0) (number)
startGGreen component of the start color (0.0 - 1.0) (number)
startBBlue component of the start color (0.0 - 1.0) (number)
endRRed component of the end color (0.0 - 1.0) (number)
endGGreen component of the end color (0.0 - 1.0) (number)
endBBlue component of the end color (0.0 - 1.0) (number)
SetGradientAlpha
Sets a gradient color shading for the texture (including opacity in the gradient).
Texture:SetGradientAlpha(“orientation“, startR, startG, startB,i
startAlpha, endR, endG, endB, endAlpha)
Gradient color shading does not change the underlying color of the texture
image, but acts as a filter: see LayeredRegion:SetVertexColor() for details.
Arguments:
orientationToken identifying the direction of the gradient (string)
HORIZONTAL - Start color on the left, end color on the right
VERTICAL - Start color at the bottom, end color at the top
startRRed component of the start color (0.0 - 1.0) (number)
startGGreen component of the start color (0.0 - 1.0) (number)
startBBlue component of the start color (0.0 - 1.0) (number)
startAlphaAlpha (opacity) for the start side of the gradient (0.0 =fully
transparent, 1.0 =fully opaque) (number)
endRRed component of the end color (0.0 - 1.0) (number)
endGGreen component of the end color (0.0 - 1.0) (number)
endBBlue component of the end color (0.0 - 1.0) (number)
endAlphaAlpha (opacity) for the end side of the gradient (0.0 =fully trans-
parent, 1.0 =fully opaque) (number)
SetNonBlocking
Sets whether the texture object loads its image file in the background.
Texture:SetNonBlocking(nonBlocking)
Chapter 29 Widget Reference 1143
Texture loading is normally synchronous, so that UI objects are not shown
partially textured while loading; however, non-blocking (asynchronous)
texture loading may be desirable in some cases where large numbers of textures
need to be loaded in a short time. This feature is used in the default UI’s
icon chooser window for macros and equipment sets, allowing a large number
of icon textures to be loaded without causing the game’s frame rate to stagger.
Arguments:
nonBlockingTrue to allow the texture object to load its image
file in the background; false (default) to halt the game engine
while the texture loads (boolean)
SetRotation
Rotates the texture image.
Texture:SetRotation(radians)
This is an efficient shorthand for the more complex Texture:
SetTexCoord().
Arguments:
radiansAmount by which the texture image should be rotated (in radians;
positive values for counter-clockwise rotation, negative for clockwise) (number)
SetTexCoord
Sets corner coordinates for scaling or cropping the texture image.
Texture:SetTexCoord(left, right, top, bottom) or i
Texture:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy)
See example for details.
Arguments:
leftLeft edge of the scaled/cropped image, as a fraction of the image’s width
from the left (number)
rightRight edge of the scaled/cropped image, as a fraction of the image’s
width from the left (number)
topTop edge of the scaled/cropped image, as a fraction of the image’s height
from the top (number)
bottomBottom edge of the scaled/cropped image, as a fraction of the image’s
height from the top (number)
ULxUpper left corner X position, as a fraction of the image’s width from the
left (number)
ULyUpper left corner Y position, as a fraction of the image’s height from the
top (number)
LLxLower left corner X position, as a fraction of the image’s width from the
left (number)
LLyLower left corner Y position, as a fraction of the image’s height from the
top (number)
URxUpper right corner X position, as a fraction of the image’s width from the
left (number)
1144 Part IV Reference
URyUpper right corner Y position, as a fraction of the image’s height from the
top (number)
LRxLower right corner X position, as a fraction of the image’s width from the
left (number)
LRyLower right corner Y position, as a fraction of the image’s height from the
top (number)
Example:
-- create a frame and texture to show the class icons
-- this image includes the icons of all player classes, arranged
-- in a 4x4 grid
CreateFrame(“Frame“,“Test“,UIParent)
Test:SetWidth(100)
Test:SetHeight(100)
Test:SetPoint(“CENTER“,0,0)
Test:CreateTexture(“TestTexture“)
TestTexture:SetAllPoints()
TestTexture:SetTexture(“Interface\\Glues\\CharacterCreate\\i
UI-CharacterCreate-Classes“)
-- the warrior icon is in the top of this 4x4 grid, so its dimensions
-- are 1/4 those of the texture image
-- scales up the warrior class icon to fill the 100x100 frame
TestTexture:SetTexCoord(0, 0.25, 0, 0.25)
SetTexCoordModifiesRect
Sets whether modifying texture coordinates scales or crops the texture image.
Texture:SetTexCoordModifiesRect(modifiesRect)
See example for details.
Arguments:
modifiesRectTrue to cause future Texture:SetTexCoord() operations
to crop the on-screen texture image; false to cause SetTexCoord to scale the
image (boolean)
Example:
-- create a frame and texture to show the class icons
CreateFrame(“Frame“,“Test“,UIParent)
Test:SetWidth(100)
Test:SetHeight(100)
Test:SetPoint(“CENTER“,0,0)
Test:CreateTexture(“TestTexture“)
TestTexture:SetAllPoints()
TestTexture:SetTexture(“Interface\\Glues\\CharacterCreate\\i
UI-CharacterCreate-Classes“)
-- with ModifiesRect enabled, SetTexCoord crops to show only the
-- warrior icon at its existing size
TestTexture:SetTexCoordModifiesRect(true)
TestTexture:SetTexCoord(0, 0.25, 0, 0.25)
Chapter 29 Widget Reference 1145
-- resetting to default texture coordinates before disabling
-- ModifiesRect, and then using SetTexCoord again scales the
-- warrior icon to fill the 100x100 pixel frame
TestTexture:SetTexCoord(0, 1, 0, 1)
TestTexture:SetTexCoordModifiesRect(false)
TestTexture:SetTexCoord(0, 0.25, 0, 0.25)
SetTexture
Sets the texture object’s image or color.
visible = Texture:SetTexture(“texture“) or Texture:SetTexture(red,i
green, blue [, alpha])
Returns nil if the texture could not be set (e.g. if the file path is invalid or
points to a file which cannot be used as a texture).
Arguments:
texture—Path to a texture image (string)
redRed component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
blueBlue component of the color (0.0 - 1.0) (number)
alpha (optional)Alpha (opacity) for the color (0.0 =fully transparent, 1.0 =
fully opaque) (number)
Returns:
visible1if the texture was successfully changed; otherwise nil (1nil)
Frame
Frame is in many ways the most fundamental widget object. Other types of widget
derivatives such as FontStrings, Textures and Animations can only be created and
attached to a Frame or other derivative of a Frame. Frames provide the basis for
interaction with the user, and registering and responding to game events.
When an addon needs to respond to game events or state changes and needs no
visible components, this is typically accomplished using a Frame. Visibly, widgets that
display game information such as threat or cooldowns and aren’t directly interactive
beyond being draggable are typically Frames. They are also commonly used as ways
to group other related frames, either visibly (such as the way the Talents pane
groups the buttons representing your character’s talents) or invisibly (such as the way
MultiBarRight groups twelve action buttons).
You create a plain frame by specifying ‘‘Frame’’ as the first argument to
CreateFrame,orwitha<Frame> element in an XML file:
-- Create a new frame in Lua
local self = CreateFrame(“Frame“, “FunWidget“, UIParent)
<Frame name=“FunWidget“ parent=“UIParent“>
<!-- insert anchors, scripts, children, and other componentsi
here in XML -->
</Frame>
1146 Part IV Reference
Frames in the FrameXML include the action bars (the frames that group the action
buttons together), the panels that display information like your character status and
quest log, and the granddaddy of the rest of the UI, UIParent.
Frame has all the methods from Region, ScriptObject and VisibleRegion, plus the
following:
Protected AllowAttributeChanges
Temporarily allows insecure code to modify the frame’s attributes during
combat.
Frame:AllowAttributeChanges()
This permission is automatically rescinded when the frame’s OnUpdate script
next runs.
CanChangeAttribute
Returns whether secure frame attributes can currently be changed.
enabled = Frame:CanChangeAttribute()
Applies only to protected frames inheriting from one of the secure frame
templates; frame attributes may only be changed by non-Blizzard scripts while
the player is not in combat (or for a short time after a secure script calls
:AllowAttributeChanges()).
Returns:
enabled1if secure frame attributes can currently be changed; otherwise nil
(1nil)
CreateFontString
Creates a new FontString as a child of the frame.
fontstring = Frame:CreateFontString([“name“ [, “layer“ [, “inherits“]]])
Arguments:
name (optional)Global name for the new font string (string)
layer (optional)Graphic layer on which to create the font string; defaults to
ARTWORK if not specified (string,layer)
inherits (optional)Name of a template from which the new front string
should inherit (string)
Returns:
fontstringReference to the new FontString object (fontstring)
CreateTexture
Creates a new Texture as a child of the frame.
texture = Frame:CreateTexture([“name“ [, “layer“ [, “inherits“]]])
Arguments:
name (optional)Global name for the new texture (string)
layer (optional)Graphic layer on which to create the texture; defaults to
ARTWORK if not specified (string,layer)
inherits (optional)Name of a template from which the new texture should
inherit (string)
Chapter 29 Widget Reference 1147
Returns:
textureReference to the new Texture object (texture)
CreateTitleRegion
Creates a title region for dragging the frame.
region = Frame:CreateTitleRegion()
Creating a title region allows a frame to be repositioned by the user (by
clicking and dragging in the region) without requiring additional scripts. (This
behavior only applies if the frame is mouse enabled.)
Returns:
regionReference to the new Region object (region)
DisableDrawLayer
Prevents display of all child objects of the frame on a specified graphics
layer.
Frame:DisableDrawLayer(“layer“)
Arguments:
layerName of a graphics layer (string,layer)
EnableDrawLayer
Allows display of all child objects of the frame on a specified graphics layer.
Frame:EnableDrawLayer(“layer“)
Arguments:
layerName of a graphics layer (string,layer)
EnableJoystick
Enables or disables joystick interactivity.
Frame:EnableJoystick(enable)
Joystick interactivity must be enabled in order for a frame’s joystick-
related script handlers to be run.
(As of this writing, joystick support is partially implemented but not enabled
in the current version of World of Warcraft.)
Arguments:
enableTrue to enable joystick interactivity; false to disable (boolean)
EnableKeyboard
Enables or disables keyboard interactivity for the frame.
Frame:EnableKeyboard(enable)
Keyboard interactivity must be enabled in order for a frame’s OnKeyDown,
OnKeyUp,orOnChar scripts to be run.
Arguments:
enableTrue to enable keyboard interactivity; false to disable
(boolean)
1148 Part IV Reference
EnableMouse
Enables or disables mouse interactivity for the frame.
Frame:EnableMouse(enable)
Mouse interactivity must be enabled in order for a frame’s mouse-
related script handlers to be run.
Arguments:
enableTrue to enable mouse interactivity; false to disable (boolean)
EnableMouseWheel
Enables or disables mouse wheel interactivity for the frame.
Frame:EnableMouseWheel(enable)
Mouse wheel interactivity must be enabled in order for a frame’s
OnMouseWheel script handler to be run.
Arguments:
enableTrue to enable mouse wheel interactivity; false to disable (boolean)
GetAttribute
Returns the value of a secure frame attribute.
value = Frame:GetAttribute(“name“)
See the secure template documentation for more information about frame
attributes.
Arguments:
nameName of an attribute to query, case insensitive (string)
Returns:
valueValue of the named attribute (value)
GetBackdrop
Returns information about the frame’s backdrop graphic.
backdrop = Frame:GetBackdrop()
See SetBackdrop.
Returns:
backdropA table containing the backdrop settings, or nil if the frame has no
backdrop (table,backdrop)
GetBackdropBorderColor
Returns the shading color for the frame’s border graphic.
red, green, blue, alpha = Frame:GetBackdropBorderColor()
Returns:
redRed component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
blueBlue component of the color (0.0 - 1.0) (number)
alpha (optional)Alpha (opacity) for the graphic (0.0 =fully transparent, 1.0 =
fully opaque) (number)
Chapter 29 Widget Reference 1149
GetBackdropColor
Returns the shading color for the frame’s background graphic.
red, green, blue, alpha = Frame:GetBackdropColor()
Returns:
redRed component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
blueBlue component of the color (0.0 - 1.0) (number)
alpha (optional)Alpha (opacity) for the graphic (0.0 =fully transparent, 1.0 =
fully opaque) (number)
GetBoundsRect
Returns the position and dimension of the smallest area enclosing the frame
and its children.
left, bottom, width, height = Frame:GetBoundsRect()
This information may not match that returned by :GetRect() if the frame
contains textures, font strings, or child frames whose boundaries lie outside its
own.
Returns:
leftDistance from the left edge of the screen to the left edge of the area (in
pixels) (number)
bottomDistance from the bottom edge of the screen to the bottom of the area
(in pixels) (number)
widthWidth of the area (in pixels) (number)
heightHeight of the area (in pixels) (number)
Example:
CreateFrame(“Frame“,“TestFrame1“, UIParent)
TestFrame1:SetWidth(100)
TestFrame1:SetHeight(100)
TestFrame1:SetPoint(“BOTTOMLEFT“,0,0)
CreateFrame(“Frame“,“TestFrame2“, TestFrame1)
TestFrame2:SetWidth(100)
TestFrame2:SetHeight(100)
TestFrame2:SetPoint(“CENTER“,TestFrame1,“TOPRIGHT“,0,0)
TestFrame1:GetBoundsRect()
-- prints “0, 0, 150, 150“
GetChildren
Returns a list of child frames of the frame.
... = Frame:GetChildren()
Returns:
...A list of the frames which are children of this frame (list)
1150 Part IV Reference
GetClampRectInsets
Returns offsets from the frame’s edges used when limiting user movement or
resizing of the frame.
left, right, top, bottom = Frame:GetClampRectInsets()
Note: despite the name of this method, the values are all offsets along the
normal axes, so to inset the frame’s clamping area from its edges, the left and
bottom measurements should be positive and the right and top measurements
should be negative.
Returns:
leftOffset from the left edge of the frame to the left edge of its clamping area
(in pixels) (number)
rightOffset from the right edge of the frame’s clamping area to the right edge
of the frame (in pixels) (number)
topOffset from the top edge of the frame’s clamping area to the top edge of
the frame (in pixels) (number)
bottomOffset from the bottom edge of the frame to the bottom edge of its
clamping area (in pixels) (number)
GetDepth
Returns the 3D depth of the frame (for stereoscopic 3D setups).
depth = Frame:GetDepth()
Returns:
depthApparent 3D depth of this frame relative to that of its parent frame
(number)
GetEffectiveAlpha
Returns the overall opacity of the frame.
alpha = Frame:GetEffectiveAlpha()
Unlike :GetAlpha() which returns the opacity of the frame relative to its
parent, this function returns the absolute opacity of the frame, taking into
account the relative opacity of parent frames.
Returns:
alphaEffective alpha (opacity) of the region (0.0 =fully transparent, 1.0 =
fully opaque) (number)
Example:
CreateFrame(“Frame“,“Frame1“, UIParent)
Frame1:SetAlpha(0.5)
CreateFrame(“Frame“,“Frame2“, Frame1)
Frame2:SetAlpha(0.2)
CreateFrame(“Frame“,“Frame3“, Frame2)
Frame3:SetAlpha(0.25)
UIParent:GetEffectiveAlpha()
-- returns 1
Chapter 29 Widget Reference 1151
Frame1:GetEffectiveAlpha()
-- returns approximately 0.5
Frame2:GetEffectiveAlpha()
-- returns approximately 0.1
Frame3:GetEffectiveAlpha()
-- returns approximately 0.025
GetEffectiveDepth
Returns the overall 3D depth of the frame (for stereoscopic 3D configurations).
depth = Frame:GetEffectiveDepth()
Unlike :GetDepth() which returns the apparent depth of the frame relative to
its parent, this function returns the absolute depth of the frame, taking into
account the relative depths of parent frames.
Returns:
depthApparent 3D depth of this frame relative to the screen (number)
Example:
CreateFrame(“Frame“,“Frame1“, UIParent)
Frame1:SetDepth(0.5)
CreateFrame(“Frame“,“Frame2“, Frame1)
Frame2:SetDepth(1)
CreateFrame(“Frame“,“Frame3“, Frame2)
Frame3:SetDepth(-0.25)
UIParent:GetEffectiveDepth()
-- returns 1
Frame1:GetEffectiveDepth()
-- returns 1.5
Frame2:GetEffectiveDepth()
-- returns 2
Frame3:GetEffectiveDepth()
-- returns 1.75
GetEffectiveScale
Returns the overall scale factor of the frame.
scale = Frame:GetEffectiveScale()
Unlike :GetScale() which returns the scale factor of the frame relative to its
parent, this function returns the absolute scale factor of the frame, taking into
account the relative scales of parent frames.
Returns:
scaleScale factor for the frame relative to its parent (number)
Example:
CreateFrame(“Frame“,“Frame1“, UIParent)
Frame1:SetScale(0.5)
CreateFrame(“Frame“,“Frame2“, Frame1)
Frame2:SetScale(1.5)
CreateFrame(“Frame“,“Frame3“, Frame2)
1152 Part IV Reference
Frame3:SetScale(0.25)
UIParent:GetEffectiveScale()
-- returns 1 (assuming the UI Scale setting in Video Options
-- is not enabled)
Frame1:GetEffectiveScale()
-- returns 0.5
Frame2:GetEffectiveDepth()
-- returns 0.75
Frame3:GetEffectiveDepth()
-- returns 0.1875
GetFrameLevel
Sets the level at which the frame is layered relative to others in its strata.
level = Frame:GetFrameLevel()
Frames with higher frame level are layered ‘‘in front of’’ frames with a lower
frame level. When not set manually, a frame’s level is determined by its place
in the frame hierarchye.g. UIParent’s level is 1, children of UIParent are at
level 2, children of those frames are at level 3, etc
Returns:
levelLayering level of the frame relative to others in its frameStrata
(number)
GetFrameStrata
Returns the general layering strata of the frame.
strata = Frame:GetFrameStrata()
Returns:
strataToken identifying the strata in which the frame should be layered
(string, frameStrata)
BACKGROUND
DIALOG
FULLSCREEN
FULLSCREEN_DIALOG
HIGH
LOW
MEDIUM
PARENT
TOOLTIP
GetHitRectInsets
Returns the insets from the frame’s edges which determine its
mouse-interactable area.
left, right, top, bottom = Frame:GetHitRectInsets()
Returns:
leftDistance from the left edge of the frame to the left edge of its
mouse-interactive area (in pixels) (number)
rightDistance from the right edge of the frame to the right edge of its
mouse-interactive area (in pixels) (number)
topDistance from the top edge of the frame to the top edge of its
mouse-interactive area (in pixels) (number)
Chapter 29 Widget Reference 1153
bottomDistance from the bottom edge of the frame to the bot-
tom edge of its mouse-interactive area (in pixels) (number)
GetID
Returns the frame’s numeric identifier.
id = Frame:GetID()
Frame IDs have no effect on frame behavior, but can be a useful way to keep
track of multiple similar frames, especially in cases where a list of frames is
created from a template (such as for action buttons, loot slots, or lines in a
FauxScrollFrame).
Returns:
idA numeric identifier for the frame (number)
GetMaxResize
Returns the maximum size of the frame for user resizing.
maxWidth, maxHeight = Frame:GetMaxResize()
Applies when resizing the frame with the mouse via :StartSizing().
Returns:
maxWidthMaximum width of the frame (in pixels), or 0for no limit
(number)
maxHeightMaximum height of the frame (in pixels), or 0for no limit
(number)
GetMinResize
Returns the minimum size of the frame for user resizing.
minWidth, minHeight = Frame:GetMinResize()
Applies when resizing the frame with the mouse via :StartSizing().
Returns:
minWidthMinimum width of the frame (in pixels), or 0for no limit (number)
minHeightMinimum height of the frame (in pixels), or 0for no limit
(number)
GetNumChildren
Returns the number of child frames belonging to the frame.
numChildren = Frame:GetNumChildren()
Returns:
numChildrenNumber of child frames belonging to the frame (number)
GetNumRegions
Returns the number of non-Frame child regions belonging to the frame.
numRegions = Frame:GetNumRegions()
Returns:
numRegionsNumber of non-Frame child regions (FontStringsand
Textures) belonging to the frame (number)
1154 Part IV Reference
GetRegions
Returns a list of non-Frame child regions belonging to the frame.
... = Frame:GetRegions()
Returns:
...A list of each non-Frame child region (FontString or Texture)belong-
ing to the frame (list)
GetScale
Returns the frame’s scale factor.
scale = Frame:GetScale()
Returns:
scaleScale factor for the frame relative to its parent (number)
GetTitleRegion
Returns the frame’s TitleRegion object.
region = Frame:GetTitleRegion()
See :CreateTitleRegion() for more information.
Returns:
regionReference to the frame’s TitleRegion object (region)
IgnoreDepth
Sets whether the frame’s depth property is ignored (for stereoscopic 3D
setups).
Frame:IgnoreDepth(enable)
If a frame’s depth property is ignored, the frame itself is not rendered with
stereoscopic 3D separation, but 3D graphics within the frame may be; this
property is used on the default UI’s WorldFrame.
Arguments:
enableTrue to ignore the frame’s depth property; false to disable
(boolean)
IsClampedToScreen
Returns whether the frame’s boundaries are limited to those of the screen.
enabled = Frame:IsClampedToScreen()
Returns:
enabled1if the frame’s boundaries are limited to those of the screen when
user moving/resizing; otherwise nil (1nil)
IsEventRegistered
Returns whether the frame is registered for a given event.
registered = Frame:IsEventRegistered(“event“)
Arguments:
event—Name of an event (string)
Chapter 29 Widget Reference 1155
Returns:
registered1if the frame is registered for the event; otherwise nil (1nil)
IsIgnoringDepth
Returns whether the frame’s depth property is ignored (for stereoscopic 3D
setups).
enabled = Frame:IsIgnoringDepth()
Returns:
enabled1if the frame’s depth property is ignored; otherwise nil (1nil)
IsJoystickEnabled
Returns whether joystick interactivity is enabled for the frame.
enabled = Frame:IsJoystickEnabled()
(As of this writing, joystick support is partially implemented but not enabled
in the current version of World of Warcraft.)
Returns:
enabled1if joystick interactivity is enabled for the frame; otherwise nil
(1nil)
IsKeyboardEnabled
Returns whether keyboard interactivity is enabled for the frame.
enabled = Frame:IsKeyboardEnabled()
Returns:
enabled1if keyboard interactivity is enabled for the frame; otherwise nil
(1nil)
IsMouseEnabled
Returns whether mouse interactivity is enabled for the frame.
enabled = Frame:IsMouseEnabled()
Returns:
enabled1if mouse interactivity is enabled for the frame; otherwise nil
(1nil)
IsMouseWheelEnabled
Returns whether mouse wheel interactivity is enabled for the frame.
enabled = Frame:IsMouseWheelEnabled()
Returns:
enabled1if mouse wheel interactivity is enabled for the frame; otherwise nil
(1nil)
IsMovable
Returns whether the frame can be moved by the user.
movable = Frame:IsMovable()
Returns:
movable1if the frame can be moved by the user; otherwise nil (1nil)
1156 Part IV Reference
IsResizable
Returns whether the frame can be resized by the user.
enabled = Frame:IsResizable()
Returns:
enabled1if the frame can be resized by the user; otherwise nil (1nil)
IsToplevel
Returns whether the frame is automatically raised to the front when clicked.
enabled = Frame:IsToplevel()
Returns:
enabled1if the frame is automatically raised to the front when clicked; other-
wise nil (1nil)
IsUserPlaced
Returns whether the frame is flagged for automatic saving and restoration of
position and dimensions.
enabled = Frame:IsUserPlaced()
Returns:
enabled1if the frame is flagged for automatic saving and restoration of posi-
tion and dimensions; otherwise nil (1nil)
Lower
Reduces the frame’s frame level below all other frames in its strata.
Frame:Lower()
Raise
Increases the frame’s frame level above all other frames in its strata.
Frame:Raise()
RegisterAllEvents
Registers the frame for all events.
Frame:RegisterAllEvents()
This method is recommended for debugging purposes only, as using it will
cause the frame’s OnEvent script handler to be run very frequently for likely
irrelevant events. (For code that needs to be run very frequently, use an
OnUpdate script handler.)
RegisterEvent
Registers the frame for an event.
Frame:RegisterEvent(“event“)
The frame’s OnEvent script handler will be run whenever the event fires. See
the event documentation for details on event arguments.
Arguments:
event—Name of an event (string)
Chapter 29 Widget Reference 1157
RegisterForDrag
Registers the frame for dragging.
Frame:RegisterForDrag(...)
Once the frame is registered for dragging (and mouse enabled), the frame’s
OnDragStart and OnDragStop scripts will be called when the specified
mouse button(s) are clicked and dragged starting from within the frame (or its
mouse-interactive area).
Arguments:
...A list of strings, each the name of a mouse button for which the frame
should respond to drag actions (list)
Button4
Button5
LeftButton
MiddleButton
RightButton
SetAttribute
Sets a secure frame attribute.
Frame:SetAttribute(“name“, value)
See the secure template documentation for more information about frame
attributes.
Arguments:
nameName of an attribute, case insensitive (string)
valueNew value to set for the attribute (value)
SetBackdrop
Sets a backdrop graphic for the frame.
Frame:SetBackdrop(backdrop)
See example for details of the backdrop table format.
Arguments:
backdropA table containing the backdrop settings, or nil to remove the
frame’s backdrop (table,backdrop)
Example:
local backdrop = {
-- path to the background texture
bgFile = “Interface\\DialogFrame\\UI-DialogBox-Gold-Background“,
-- path to the border texture
edgeFile = “Interface\\DialogFrame\\UI-DialogBox-Gold-Border“,
-- true to repeat the background texture to fill the frame,
-- false to scale it
tile = true,
-- size (width or height) of the square repeating background
-- tiles (in pixels)
tileSize = 32,
-- thickness of edge segments and square size of edge corners
1158 Part IV Reference
-- (in pixels)
edgeSize = 32,
-- distance from the edges of the frame to those of the background
-- texture (in pixels)
insets = {
left = 11,
right = 12,
top = 12,
bottom = 11
}
}
-- replaces the game menu’s backdrop with the gold backdrop
-- used in Bind-On-Pickup loot roll frames
GameMenuFrame:SetBackdrop(backdrop)
SetBackdropBorderColor
Sets a shading color for the frame’s border graphic.
Frame:SetBackdropBorderColor(red, green, blue [, alpha])
As with Texture:SetVertexColor(), this color is a shading applied to the
colors of the texture image; a color of (1, 1, 1) allows the image’s original
colors to show.
Arguments:
redRed component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
blueBlue component of the color (0.0 - 1.0) (number)
alpha (optional)Alpha (opacity) for the graphic (0.0 =fully transparent, 1.0 =
fully opaque) (number)
SetBackdropColor
Sets a shading color for the frame’s background graphic.
Frame:SetBackdropColor(red, green, blue [, alpha])
As with Texture:SetVertexColor(), this color is a shading applied to the
colors of the texture image; a color of (1, 1, 1) allows the image’s original
colors to show.
Arguments:
redRed component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
blueBlue component of the color (0.0 - 1.0) (number)
alpha (optional)Alpha (opacity) for the graphic (0.0 =fully transparent, 1.0 =
fully opaque) (number)
SetClampRectInsets
Sets offsets from the frame’s edges used when limiting user movement or
resizing of the frame.
Frame:SetClampRectInsets(left, right, top, bottom)
Chapter 29 Widget Reference 1159
Note: despite the name of this method, the parameters are offsets along the
normal axesto inset the frame’s clamping area from its edges, the left and
bottom measurements should be positive and the right and top measurements
should be negative.
Arguments:
leftOffset from the left edge of the frame to the left edge of its clamping area
(in pixels) (number)
rightOffset from the right edge of the frame’s clamping area to the right edge
of the frame (in pixels) (number)
topOffset from the top edge of the frame’s clamping area to the top edge of
the frame (in pixels) (number)
bottomOffset from the bottom edge of the frame to the bottom edge of its
clamping area (in pixels) (number)
Example:
-- creates a drag-movable frame which cannot be moved beyondi
the edges of the screen
CreateFrame(“Frame“,“Test“,UIParent)
Test:SetWidth(100)
Test:SetHeight(100)
Test:SetPoint(“CENTER“)
Test:EnableMouse(true)
Test:SetClampedToScreen(true)
Test:CreateTexture(“TestBG“)
TestBG:SetAllPoints()
TestBG:SetTexture(1,1,1,0.5)
Title=Test:CreateTitleRegion()
Title:SetAllPoints()
-- inset the clamping area, allowing the frame to be moved partially
-- offscreen by 50 pixels in any direction
Test:SetClampRectInsets(50,-50,-50,50)
-- outset the clamping area, allowing the frame to be movedi
no closer than 50 pixels to any edge of the screen
Test:SetClampRectInsets(-50,50,50,-50)
SetClampedToScreen
Sets whether the frame’s boundaries should be limited to those of the screen.
Frame:SetClampedToScreen(enable)
Applies to user moving/resizing of the frame (via :StartMoving(),
:StartSizing(), or title region); attempting to move or resize the frame
beyond the edges of the screen will move/resize it no further than the edge of
the screen closest to the mouse position. Does not apply to programmatically
setting the frame’s position or size.
Arguments:
enableTrue to limit the frame’s boundaries to those of the screen; false
to allow the frame to be moved/resized without such limits (boolean)
1160 Part IV Reference
SetDepth
Sets the 3D depth of the frame (for stereoscopic 3D configurations).
Frame:SetDepth(depth)
Arguments:
depthApparent 3D depth of this frame relative to that of its parent frame
(number)
SetFrameLevel
Sets the level at which the frame is layered relative to others in its strata.
Frame:SetFrameLevel(level)
Frames with higher frame level are layered in front offrames with a lower
frame level.
Arguments:
levelLayering level of the frame relative to others in its frameStrata
(number)
SetFrameStrata
Sets the general layering strata of the frame.
Frame:SetFrameStrata(“strata“)
Where frame level provides fine control over the layering of frames, frame
strata provides a coarser level of layering control: frames in a higher strata
always appear in front offrames in lower strata regardless of frame level.
Arguments:
strataToken identifying the strata in which the frame should be layered
(string, frameStrata)
SetHitRectInsets
Sets the insets from the frame’s edges which determine its mouse-interactable
area.
Frame:SetHitRectInsets(left, right, top, bottom)
Arguments:
leftDistance from the left edge of the frame to the left edge of its
mouse-interactive area (in pixels) (number)
rightDistance from the right edge of the frame to the right edge of its
mouse-interactive area (in pixels) (number)
topDistance from the top edge of the frame to the top edge of its
mouse-interactive area (in pixels) (number)
bottomDistance from the bottom edge of the frame to the bot-
tom edge of its mouse-interactive area (in pixels) (number)
SetID
Sets a numeric identifier for the frame.
Frame:SetID(id)
Chapter 29 Widget Reference 1161
Frame IDs have no effect on frame behavior, but can be a useful way to keep
track of multiple similar frames, especially in cases where a list of frames is
created from a template (such as for action buttons, loot slots, or lines in a
FauxScrollFrame).
Arguments:
idA numeric identifier for the frame (number)
SetMaxResize
Sets the maximum size of the frame for user resizing.
Frame:SetMaxResize(maxWidth, maxHeight)
Applies when resizing the frame with the mouse via :StartSizing().
Arguments:
maxWidthMaximum width of the frame (in pixels), or 0for no limit (number)
maxHeightMaximum height of the frame (in pixels), or 0for no limit
(number)
SetMinResize
Sets the minimum size of the frame for user resizing.
Frame:SetMinResize(minWidth, minHeight)
Applies when resizing the frame with the mouse via :StartSizing().
Arguments:
minWidthMinimum width of the frame (in pixels), or 0for no limit (number)
minHeightMinimum height of the frame (in pixels), or 0for no limit (number)
SetMovable
Sets whether the frame can be moved by the user.
Frame:SetMovable(enable)
Enabling this property does not automatically implement behaviors allowing
the frame to be dragged by the usersuch behavior must be implemented in
the frame’s mouse script handlers. If this property is not enabled,
Frame:StartMoving() causes a Lua error.
For simple automatic frame dragging behavior, see Frame:
CreateTitleRegion().
Arguments:
enableTrue toallowtheframetobemovedbytheuser;false to disable
(boolean)
SetResizable
Sets whether the frame can be resized by the user.
Frame:SetResizable(enable)
Enabling this property does not automatically implement behaviors allowing
the frame to be drag-resized by the usersuch behavior must be implemented
in the frame’s mouse script handlers. If this property is not enabled,
Frame:StartSizing() causes a Lua error.
1162 Part IV Reference
Arguments:
enableTrue toallowtheframetoberesizedbytheuser;false to disable
(boolean)
SetScale
Sets the frame’s scale factor.
Frame:SetScale(scale)
A frame’s scale factor affects the size at which it appears on the screen relative
to that of its parent. The entire interface may be scaled by changing
UIParent’s scale factor (as can be done via the Use UI Scale setting in the
default interface’s Video Options panel).
Arguments:
scaleScale factor for the frame relative to its parent (number)
Example:
-- creates three concentric squares colored red, green and blue
-- each is 100 pixels wide according to its own coordinate system
-- but the actual size of each is determined by its scale factor:
-- - the red square is about 50 pixels square, or 0.5x its normal
-- size (assuming UIParent’s scale factor is 1)
-- - the green square is about 75 pixels square, or 1.5x the size
-- of the red square
-- - the blue square is about 19 pixels square, or 0.25x the size
-- of the green square
CreateFrame(“Frame“,“Frame1“, UIParent)
Frame1:SetWidth(100)
Frame1:SetHeight(100)
Frame1:SetPoint(“CENTER“)
Frame1:CreateTexture(“Frame1BG“)
Frame1BG:SetTexture(1,0,0,0.5)
Frame1BG:SetAllPoints()
Frame1:SetScale(0.5)
CreateFrame(“Frame“,“Frame2“, Frame1)
Frame2:SetWidth(100)
Frame2:SetHeight(100)
Frame2:SetPoint(“CENTER“)
Frame2:CreateTexture(“Frame2BG“)
Frame2BG:SetTexture(0,1,0,0.5)
Frame2BG:SetAllPoints()
Frame2:SetScale(1.5)
CreateFrame(“Frame“,“Frame3“, Frame2)
Frame3:SetWidth(100)
Frame3:SetHeight(100)
Frame3:SetPoint(“CENTER“)
Frame3:CreateTexture(“Frame3BG“)
Frame3BG:SetTexture(0,0,1,0.5)
Frame3BG:SetAllPoints()
Frame3:SetScale(0.25)
Chapter 29 Widget Reference 1163
SetToplevel
Sets whether the frame should automatically come to the front when clicked.
Frame:SetToplevel(enable)
When a frame with Toplevel behavior enabled is clicked, it automatically
changes its frame level such that it is greater than (and therefore drawn ‘‘in
front of’’) all other frames in its strata.
Arguments:
enableTrue to cause the frame to automatically come to the front when
clicked; false otherwise (boolean)
SetUserPlaced
Flags the frame for automatic saving and restoration of position and
dimensions.
Frame:SetUserPlaced(enable)
The position and size of frames so flagged is automatically saved when the UI
is shut down (as when quitting, logging out, or reloading) and restored when
the UI next starts up (as when logging in or reloading). As implied by its name,
enabling this property is useful for frames which can be moved or resized by
the user.
Arguments:
enableTrue to enable automatic saving and restoration of the
frame’s position and dimensions; false to disable (boolean)
StartMoving
Begins repositioning the frame via mouse movement.
Frame:StartMoving()
StartSizing
Begins resizing the frame via mouse movement.
Frame:StartSizing()
StopMovingOrSizing
Ends movement or resizing of the frame initiated with :StartMoving() or
:StartSizing().
Frame:StopMovingOrSizing()
UnregisterAllEvents
Unregisters the frame from any events for which it is registered.
Frame:UnregisterAllEvents()
UnregisterEvent
Unregisters the frame for an event.
Frame:UnregisterEvent(“event“)
Once unregistered, the frame’s OnEvent script handler will not be called for
that event.
1164 Part IV Reference
Unregistering from notifications for an event can be useful for improving
addon performance at times when it’s not necessary to process the event. For
example, a frame which monitors target health does not need to receive the
UNIT_HEALTH event while the player has no target. An addon that sorts the
contents of the player’s bags can register for the BAG_UPDATE event to keep
track of when items are picked up, but unregister from the event while it
performs its sorting.
Arguments:
event—Name of an event (string)
Button
Of all the various subtypes of Frame in the user interface system, Buttons are the
most visible, since users interact with them frequently during gameplay. They are the
primary means by which the user controls the game and their characters.
Buttons have an intrinsic FontString built-in, so they support both the SetText and the
GetText methods. In addition, a button has three special visual states that can be dec-
orated independently: one when the button is disabled, one when the button has been
pushed but not yet released, and one when the mouse is over the button. The changes
to the button’s presentation happen automatically based on the button’s definition.
The most important aspect of a Button is the fact that it can be clicked by the
user. When a button is clicked the PreClick script handler will fire, followed by the
OnClick handler, and finally the PostClick handler. These allow an addon developer
lots of flexibility when creating an addon, especially in the presence of the secure
environment and tainting system introduced in WoW 2.0.
To create a button, call CreateFrame with ‘‘Button’’ as the first argument, or
construct one in an XML file with a <Button> element. Some handy templates
for this include UIPanelButtonTemplate (which provides a standard red button),
UIPanelCloseButton (a small red square with a yellow X in it) and SecureHan-
dlerClickTemplate.
The most famous Buttons are probably unit frames, which make use of the SecureAc-
tionButtonTemplate (or its derivative, SecureUnitButtonTemplate) to control targeting
and sometimes spell-casting. There are many insecure buttons as well (or more accu-
rately, buttons which do not require security), such as the micro buttons on the action
bar for opening various panels and menus, or the buttons around the minimap for
revealing the calendar or displaying the world map.
Button has all the methods from Frame, plus the following:
Click
Performs a (virtual) mouse click on the button.
Button:Click(“button“, down)
Causes any of the button’s mouse click-related scripts to be run as if the button
were clicked by the user.
Calling this method can result in an error if the button inherits from a secure
frame template and performs protected actions.
Chapter 29 Widget Reference 1165
Arguments:
buttonNameofthemousebuttonfortheclickaction(string)
Button4
Button5
LeftButton
MiddleButton
RightButton
downTrue for a ‘‘mouse down’’ click action, false for ‘‘mouse up’’ or other
click actions (boolean)
Disable
Disallows user interaction with the button.
Button:Disable()
Automatically changes the visual state of the button if its
DisabledTexture, DisabledTextColor or DisabledFontObject
are set.
Enable
Allows user interaction with the button.
Button:Enable()
If a disabled appearance was specified for the button, automatically returns the
button to its normal appearance.
GetButtonState
Returns the button’s current state.
state = Button:GetButtonState()
Returns:
stateState of the button (string)
DISABLED - Button is disabled and cannot receive user input
NORMAL - Button is in its normal state
PUSHED - Button is pushed (as during a click on the button)
GetDisabledFontObject
Returns the font object used for the button’s disabled state.
font = Button:GetDisabledFontObject()
Returns:
fontReference to the Font object used when the button is disabled (font)
GetDisabledTexture
Returns the texture used when the button is disabled.
texture = Button:GetDisabledTexture()
Returns:
textureReference to the Texture object used when the button is disabled
(texture)
1166 Part IV Reference
GetFontString
Returns the FontString object used for the button’s label text.
fontstring = Button:GetFontString()
Returns:
fontstringReference to the FontString object used for the button’s label
text (fontstring)
GetHighlightFontObject
Returns the font object used when the button is highlighted.
font = Button:GetHighlightFontObject()
Returns:
fontReference to the Font object used when the button is highlighted (font)
GetHighlightTexture
Returns the texture used when the button is highlighted.
texture = Button:GetHighlightTexture()
Returns:
textureReference to the Texture object used when the button is highlighted
(texture)
GetNormalFontObject
Returns the font object used for the button’s normal state.
font = Button:GetNormalFontObject()
Returns:
fontReference to the Font object used for the button’s normal state (font)
GetNormalTexture
Returns the texture used for the button’s normal state.
texture = Button:GetNormalTexture()
Returns:
textureReference to the Texture object used for the button’s normal state
(texture)
GetPushedTextOffset
Returns the offset for moving the button’s label text when pushed.
x, y = Button:GetPushedTextOffset()
Returns:
xHorizontal offset for the text (in pixels; values increasing to the right)
(number)
yVertical offset for the text (in pixels; values increasing upward) (number)
GetPushedTexture
Returns the texture used when the button is pushed.
texture = Button:GetPushedTexture()
Chapter 29 Widget Reference 1167
Returns:
textureReference to the Texture object used when the button is pushed
(texture)
GetText
Returns the text of the button’s label.
text = Button:GetText()
Returns:
textText of the button’s label (string)
GetTextHeight
Returns the height of the button’s text label.
height = Button:GetTextHeight()
Reflects the height of the rendered text (which increases if the text wraps onto
two lines), not the point size of the text’s font.
Returns:
heightHeight of the button’s text (in pixels) (number)
GetTextWidth
Returns the width of the button’s text label.
width = Button:GetTextWidth()
Returns:
widthWidth of the button’s text (in pixels) (number)
IsEnabled
Returns whether user interaction with the button is allowed.
enabled = Button:IsEnabled()
Returns:
enabled1if user interaction with the button is allowed; otherwise nil (1nil)
LockHighlight
Locks the button in its highlight state.
Button:LockHighlight()
When the highlight state is locked, the button will always appear highlighted
regardless of whether it is moused over.
RegisterForClicks
Registers a button to receive mouse clicks.
Button:RegisterForClicks(...)
Arguments:
...A list of strings, each the combination of a button name and click action for
which the button’s click-related script handlers should be run. Possible values:
(list)
1168 Part IV Reference
Button4Down
Button4Up
Button5Down
Button5Up
LeftButtonDown
LeftButtonUp
MiddleButtonDown
MiddleButtonUp
RightButtonDown
RightButtonUp
AnyDown
AnyUp
AnyDown and AnyUp respond to the down or up action of any mouse button.
SetButtonState
Sets the button’s state.
Button:SetButtonState(“state“, lock)
Arguments:
stateState for the button (string)
DISABLED - Button is disabled and cannot receive user input
NORMAL - Button is in its normal state
PUSHED - Button is pushed (as during a click on the button)
lockLocks the button in the given state; e.g. if NORMAL, the button
cannot be clicked but remains in the NORMAL state (boolean)
SetDisabledFontObject
Sets the font object used for the button’s disabled state.
Button:SetDisabledFontObject(font)
Arguments:
fontReference to a Font object to be used when the button is disabled (font)
SetDisabledTexture
Sets the texture used when the button is disabled.
Button:SetDisabledTexture(texture) or i
Button:SetDisabledTexture(“filename“)
Arguments:
textureReference to an existing Texture object (texture)
filenamePath to a texture image file (string)
SetFontString
Sets the FontString object used for the button’s label text.
Button:SetFontString(fontstring)
Arguments:
fontstringReference to a FontString object to be used for the button’s
label text (fontstring)
SetFormattedText
Sets the button’s label text using format specifiers.
Button:SetFormattedText(“formatString“, ...)
Equivalent to :SetText(format(format, ...)),butdoesnotcreatea
throwaway Lua string object, resulting in greater memory-usage efficiency.
Chapter 29 Widget Reference 1169
Arguments:
formatStringA string containing format specifiers (as with
string.format())(string)
...A list of values to be included in the formatted string (list)
SetHighlightFontObject
Sets the font object used when the button is highlighted.
Button:SetHighlightFontObject(font)
Arguments:
fontReference to a Font object to be used when the button is highlighted
(font)
SetHighlightTexture
Sets the texture used when the button is highlighted.
Button:SetHighlightTexture(texture [, “mode“]) or i
Button:SetHighlightTexture(“filename“ [, “mode“])
Unlike the other button textures for which only one is visible at a time, the
button’s highlight texture is drawn on top of its existing (normal or pushed)
texture; thus, this method also allows specification of the texture’s blend
mode.
Arguments:
textureReference to an existing Texture object (texture)
filenamePath to a texture image file (string)
mode (optional)Blend mode for the texture; defaults to ADD if omitted
(string)
ADD - Adds texture color values to the underlying color values, using the
alpha channel; light areas in the texture lighten the background while dark
areas are more transparent
ALPHAKEY - One-bit transparency; pixels with alpha values greater than 0.8
are treated as fully opaque and all other pixels are treated as fully trans-
parent
BLEND - Normal color blending, using any alpha channel in the texture
image
DISABLE - Ignores any alpha channel, displaying the texture as fully opaque
MOD - Ignores any alpha channel in the texture and multiplies
texture color values by background color values; dark areas in the
texture darken the background while light areas are more transparent
SetNormalFontObject
Sets the font object used for the button’s normal state.
Button:SetNormalFontObject(font)
Arguments:
fontReference to a Font object to be used in the button’s normal state
(font)
1170 Part IV Reference
SetNormalTexture
Sets the texture used for the button’s normal state.
Button:SetNormalTexture(texture) or Button:SetNormalTexture
(“filename“)
Arguments:
textureReference to an existing Texture object (texture)
filenamePath to a texture image file (string)
SetPushedTextOffset
Sets the offset for moving the button’s label text when pushed.
Button:SetPushedTextOffset(x, y)
Moving the button’s text while it is being clicked can provide an illusion of 3D
depth for the buttonin the default UI’s standard button templates, this offset
matches the apparent movement seen in the difference between the buttons’
normal and pushed textures.
Arguments:
xHorizontal offset for the text (in pixels; values increasing to the right)
(number)
yVertical offset for the text (in pixels; values increasing upward) (number)
SetPushedTexture
Sets the texture used when the button is pushed.
Button:SetPushedTexture(texture) or Button:SetPushedTexture
(“filename“)
Arguments:
textureReference to an existing Texture object (texture)
filenamePath to a texture image file (string)
SetText
Sets the text displayed as the button’s label.
Button:SetText(“text“)
Arguments:
textText to be displayed as the button’s label (string)
UnlockHighlight
Unlocks the button’s highlight state.
Button:UnlockHighlight()
Can be used after a call to :LockHighlight() to restore the button’s normal
mouseover behavior.
CheckButton
CheckButtons are a specialized form of Button; they maintain an on/off state, which
toggles automatically when they are clicked, and additional textures for when they
Chapter 29 Widget Reference 1171
are checked, or checked while disabled. A CheckButton’s checked status can also be
checked or set directly from Lua with :GetChecked() and :SetChecked().Check-
Buttons do not need to look like checkboxes; the configurable checked textures allow
you to create whatever appearance is suitable for a button that needs a persistent state.
While CheckButtons are particularly prevalent throughout the Interface Options UI,
they are also found in places like the crafting UI (to restrict display of known recipes to
those for which the materials are available). The most frequently used CheckButtons,
however, are the action buttons on your action bars. They use the checked state to
display a yellow border around spells or actions that are currently in progress, and
include update code to adjust the checked state appropriately.
Although CheckButtons inherit the Button type’s :SetText() and :GetText()
methods, most CheckButtons templates are not set up to display their labels in this
way. Instead, they include a FontString with the name $parentText,sothatyouset
their text with _G[button:GetName()..“Text“]:SetText(newLabel).
Some convenient CheckButton templates include UICheckButtonTemplate (the con-
ventional general-purpose check button), InterfaceOptionsCheckButtonTemplate (for
use with Interface Options panels) and ActionBarButtonTemplate.
CheckButton has all the methods from Button, plus the following:
GetChecked
Returns whether the check button is checked.
enabled = CheckButton:GetChecked()
Returns:
enabled1if the button is checked; nil if the button is unchecked (1nil)
GetCheckedTexture
Returns the texture used when the button is checked.
texture = CheckButton:GetCheckedTexture()
Returns:
textureReference to the Texture object used when the button is checked
(texture)
GetDisabledCheckedTexture
Returns the texture used when the button is disabled and checked.
texture = CheckButton:GetDisabledCheckedTexture()
Returns:
textureReference to the Texture object used when the button is disabled
and checked (texture)
SetChecked
Sets whether the check button is checked.
CheckButton:SetChecked(enable)
Arguments:
enableTrue to check the button; false to uncheck (boolean)
1172 Part IV Reference
SetCheckedTexture
Sets the texture used when the button is checked.
CheckButton:SetCheckedTexture(texture) or i
CheckButton:SetCheckedTexture(“filename“)
Arguments:
textureReference to an existing Texture object (texture)
filenamePath to a texture image file (string)
SetDisabledCheckedTexture
Sets the texture used when the button is disabled and checked.
CheckButton:SetDisabledCheckedTexture(texture) or i
CheckButton:SetDisabledCheckedTexture(“filename“)
Arguments:
textureReference to an existing Texture object (texture)
filenamePath to a texture image file (string)
ColorSelect
ColorSelect is a very specialized type of frame with a specific purpose; to allow the user
to interactively select a color, typically to control the appearance of another UI element.
Primarily used to allow the player to control the appearance of chat messages in
different channels, they are also used when creating a tabard to control the color scheme.
While the ColorSelect type gives you fairly detailed control over the appearance
of the color wheel and value slider, the standard Color picker frame as defined in
FrameXML/ColorPickerFrame.xml is preconfigured and usually adequate to your
needs. You will usually be most interested in the SetColor methods (to load a color you
have stored for a particular element) and the GetColor methods (to retrieve the new
color chosen by the user). ColorSelect supports both RGB and HSV color descriptions.
ColorSelect has all the methods from Frame, plus the following:
GetColorHSV
Returns the hue, saturation and value of the currently selected color.
hue, saturation, value = ColorSelect:GetColorHSV()
Returns:
hueHue of the selected color (angle on the color wheel in degrees; 0 =red,
increasing counter-clockwise) (number)
saturationSaturation of the selected color (0.0 - 1.0) (number)
valueValue of the selected color (0.0 - 1.0) (number)
GetColorRGB
Returns the red, green and blue components of the currently selected color.
red, blue, green = ColorSelect:GetColorRGB()
Returns:
redRed component of the color (0.0 - 1.0) (number)
blueBlue component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
Chapter 29 Widget Reference 1173
GetColorValueTexture
Returns the texture for the color picker’s value slider background.
texture = ColorSelect:GetColorValueTexture()
The color picker’s value slider displays a value gradient (and allows control
of the color’s value component) for whichever hue and saturation is selected in
the color wheel. (In the default UI’s ColorPickerFrame, this part is found to the
right of the color wheel.)
Returns:
textureReference to the Texture object used for drawing the value slider
background (texture)
GetColorValueThumbTexture
Returns the texture for the color picker’s value slider thumb.
texture = ColorSelect:GetColorValueThumbTexture()
The color picker’s value slider displays a value gradient (and allows control
of the color’s value component) for whichever hue and saturation is selected in
the color wheel. (In the default UI’s ColorPickerFrame, this part is found to the
right of the color wheel.) The thumb texture is the movable part indicating the
current value selection.
Returns:
textureReference to the Texture object used for drawing the slider thumb
(texture)
GetColorWheelTexture
Returns the texture for the color picker’s hue/saturation wheel.
texture = ColorSelect:GetColorWheelTexture()
Returns:
textureReference to the Texture object used for drawing the hue/saturation
wheel (texture)
GetColorWheelThumbTexture
Returns the texture for the selection indicator on the color picker’s
hue/saturation wheel.
texture = ColorSelect:GetColorWheelThumbTexture()
Returns:
textureReference to the Texture object used for drawing the hue/saturation
wheel’s selection indicator (texture)
SetColorHSV
Sets the color picker’s selected color by hue, saturation and value.
ColorSelect:SetColorHSV(hue, saturation, value)
Arguments:
hueHue of a color (angle on the color wheel in degrees; 0 =red, increasing
counter-clockwise) (number)
saturationSaturation of a color (0.0 - 1.0) (number)
valueValue of a color (0.0 - 1.0) (number)
1174 Part IV Reference
SetColorRGB
Sets the color picker’s selected color by red, green and blue components.
ColorSelect:SetColorRGB(red, blue, green)
Arguments:
redRed component of the color (0.0 - 1.0) (number)
blueBlue component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
SetColorValueTexture
Sets the Texture object used to display the color picker’s value slider.
ColorSelect:SetColorValueTexture(texture)
The color picker’s value slider displays a value gradient (and allows control
of the color’s value component) for whichever hue and saturation is selected in
the color wheel. In the default UI’s ColorPickerFrame, this part is found to the
right of the color wheel.
This method does not allow changing the texture image displayed for the
slider background; rather, it allows customization of the size and placement of
the Texture object into which the game engine draws the color value gradient.
Arguments:
textureReference to a Texture object (texture)
SetColorValueThumbTexture
Sets the texture for the color picker’s value slider thumb.
ColorSelect:SetColorValueThumbTexture(texture) or i
ColorSelect:SetColorValueThumbTexture(“filename“)
The color picker’s value slider displays a value gradient (and allows control of
the color’s value component) for whichever hue and saturation is selected in
the color wheel. (In the default UI’s ColorPickerFrame, this part is found to the
right of the color wheel.) The thumb texture is the movable part indicating the
current value selection.
Arguments:
textureReference to an existing Texture object (texture)
filenamePath to a texture image file (string)
SetColorWheelTexture
Sets the Texture object used to display the color picker’s hue/saturation
wheel.
ColorSelect:SetColorWheelTexture(texture)
This method does not allow changing the texture image displayed for the color
wheel; rather, it allows customization of the size and placement of the Texture
object into which the game engine draws the standard color wheel image.
Chapter 29 Widget Reference 1175
Arguments:
textureReference to a Texture object (texture)
SetColorWheelThumbTexture
Sets the texture for the selection indicator on the color picker’s hue/saturation
wheel.
ColorSelect:SetColorWheelThumbTexture(texture) or i
ColorSelect:SetColorWheelThumbTexture(“filename“)
Arguments:
textureReference to an existing Texture object (texture)
filenamePath to a texture image file (string)
Cooldown
Cooldown is a specialized variety of Frame that displays the little ‘‘clock’’ effect over
abilities and buffs. It can be set with its running time, whether it should appear to
‘‘fill up’’ or ‘‘empty out’’, and whether or not there should be a bright edge where it’s
changing between dim and bright.
Cooldowns are usually children of another frame, and typically set to cover the
same area as that frame, or almost all of it. In the stock UI, they are used mostly to
display cooldowns on action buttons and buffs or debuffs on targets.
Cooldown has all the methods from Frame, plus the following:
GetDrawEdge
Returns whether a bright line should be drawn on the moving edge of the
cooldown animation.
enabled = Cooldown:GetDrawEdge()
Returns:
enabled1if a bright line should be drawn on the moving edge
of the cooldown ‘‘sweep’’ animation; otherwise nil (1nil)
GetReverse
Returns whether the bright and dark portions of the cooldown animation
should be inverted.
enabled = Cooldown:GetReverse()
Returns:
enabled1if the cooldown animation ‘‘sweeps’’ an area of dark-
ness over the underlying image; nil if the animation darkens the
underlying image and ‘‘sweeps’’ the darkened area away (1nil)
SetCooldown
Sets up the parameters for a Cooldown model.
Cooldown:SetCooldown(start, duration)
1176 Part IV Reference
Note: Most Cooldown animations in the default UI are managed via the
function CooldownFrame_SetTimer(self, start, duration, enable),a
wrapper for this method which automatically shows the Cooldown element
while animating and hides it otherwise.
Arguments:
start—Value of GetTime() at the start of the cooldown animation (number)
durationDuration of the cooldown animation (excluding that of the final
‘‘flash’’ animation) (number)
Example:
-- creates a Cooldown object over the player portrait
CreateFrame(“Cooldown“,“PlayerCooldown“,PlayerFrame)
PlayerCooldown:SetAllPoints(PlayerPortrait)
-- performs a complete cooldown “sweep“ animation over 10 seconds
PlayerCooldown:SetCooldown(GetTime(), 10)
-- performs the same animation, starting halfway in (5 seconds)
PlayerCooldown:SetCooldown(GetTime() - 5, 10)
-- performs only the “flash“ animation normally seen at the end
-- of a cooldown
PlayerCooldown:SetCooldown(0,0)
SetDrawEdge
Sets whether a bright line should be drawn on the moving edge of the
cooldown animation.
Cooldown:SetDrawEdge(enable)
Does not change the appearance of a currently running cooldown animation;
only affects future runs of the animation.
Arguments:
enableTrue tocauseabrightlinetobedrawnonthemovingedgeofthe
cooldown ‘‘sweep’’ animation; false for the default behavior (no line drawn)
(boolean)
SetReverse
Sets whether to invert the bright and dark portions of the cooldown animation.
Cooldown:SetReverse(reverse)
Arguments:
reverseTrue for an animation ‘‘sweeping’’ an area of darkness
over the underlying image; false for the default animation of darkening
the underlying image and ‘‘sweeping’’ the darkened area away (boolean)
GameTooltip
GameTooltips are used to display explanatory information relevant to a particular
element of the game world. They offer almost innumerable methods for setting the
Chapter 29 Widget Reference 1177
specific object, creature or ability the tooltip should describe, and a smaller number of
methods for querying what it is that the tooltip is currently describing.
GameTooltips are sufficiently complicated that an entire chapter is dedicated to
describing them. In addition to methods for setting their contents, they also support
options controlling their positioning and visibility on screen, as well as methods to
facilitate adding more text to them (for instance, an addon that displays, in the tooltip
for a soul shard created by a warlock, the name of the player or monster from which
the shard was collected).
While most of the heavy lifting is done by the frame called simply GameTooltip,
there is also one called ItemRefTooltip that does the work of displaying information
about items linked in chat when they are clicked.
GameTooltip has all the methods from Frame, plus the following:
AddDoubleLine
Adds a line to the tooltip with both left-side and right-side portions.
GameTooltip:AddDoubleLine(“textLeft“, “textRight“ i
[, rL [, gL [, bL [, rR [, gR [, bR]]]]]])
The tooltip is not automatically resized to fit the added line; to do so, call the
tooltip’s :Show() method after adding lines.
Arguments:
textLeftText to be displayed on the left side of the new line (string)
textRightTexttobedisplayedontherightsideofthenewline(string)
rL (optional)Red component of the color for the left-side text (0.0 - 1.0)
(number)
gL (optional)Green component of the color for the left-side text (0.0 - 1.0)
(number)
bL (optional)Blue component of the color for the left-side text (0.0 - 1.0)
(number)
rR (optional)Red component of the color for the right-side text
(0.0 - 1.0) (number)
gR (optional)Green component of the color for the right-side text (0.0 - 1.0)
(number)
bR (optional)Blue component of the color for the right-side text (0.0 - 1.0)
(number)
AddFontStrings
Adds FontString objects to the tooltip, allowing it to display an additional
line of text.
GameTooltip:AddFontStrings(left, right)
This method is of little utility outside of Blizzard scripts, as the tooltip
automatically creates new font strings for additional lines as needed.
Arguments:
leftReference to a FontString object for the left-side text of a new line
(fontstring)
1178 Part IV Reference
rightReference to a FontString object for the right-side text of a new line
(fontstring)
AddLine
Adds a line of text to the tooltip.
GameTooltip:AddLine(“text“ [, r [, g [, b [, wrap]]]])
The tooltip is not automatically resized to fit the added line (and wrap it, if
applicable); to do so, call the tooltip’s :Show() method after adding lines.
Arguments:
textText to be added as a new line in the tooltip (string)
r(optional)Red component of the text color (0.0 - 1.0) (number)
g(optional)Green component of the text color (0.0 - 1.0) (number)
b(optional)Blue component of the text color (0.0 - 1.0) (number)
wrap (optional)True tocausethelinetowrapifitislongerthanother,
non-wrapping lines in the tooltip or longer than the tooltip’s forced width
(boolean)
AddTexture
Adds a texture to the last tooltip line.
GameTooltip:AddTexture(“texture“)
The texture is sized to match the height of the line’s text and positioned to the
left of the text (indenting the text to provide room).
Arguments:
texturePath to a texture image file (string)
AppendText
Adds text to the first line of the tooltip.
GameTooltip:AppendText(“text“)
Arguments:
textText to be appended to the tooltip’s first line (string)
ClearLines
Clears the tooltip’s contents.
GameTooltip:ClearLines()
Scripts scanning the tooltip contents should be aware that this method clears
the text of all the tooltip’s left-side font strings but hides the right-side font
strings without clearing their text.
FadeOut
Causes the tooltip to begin fading out.
GameTooltip:FadeOut()
GetAnchorType
Returns the method for anchoring the tooltip relative to its owner.
anchor = GameTooltip:GetAnchorType()
Chapter 29 Widget Reference 1179
Returns:
anchorToken identifying the method for anchoring the tooltip relative to its
owner frame (string)
ANCHOR_BOTTOMLEFT - Align the top right of the tooltip with the bottom left
of the owner
ANCHOR_CURSOR - Tooltip follows the mouse cursor
ANCHOR_LEFT - Align the bottom right of the tooltip with the top left of the
owner
ANCHOR_NONE - Tooltip appears in the default position
ANCHOR_PRESERVE - Tooltip’s position is saved between sessions (useful if the
tooltip is made user-movable)
ANCHOR_RIGHT - Align the bottom left of the tooltip with the top right of the
owner
ANCHOR_TOPLEFT - Align the bottom left of the tooltip with the top left of the
owner
ANCHOR_TOPRIGHT - Align the bottom right of the tooltip with the top right of
the owner
GetItem
Returns the name and hyperlink for the item displayed in the tooltip.
name, link = GameTooltip:GetItem()
Returns:
nameName of the item whose information is displayed in the tooltip, or nil.
(string)
linkA hyperlink for the item (string, hyperlink)
GetMinimumWidth
Returns the minimum width of the tooltip.
width = GameTooltip:GetMinimumWidth()
Returns:
widthMinimum width of the tooltip frame (in pixels) (number)
GetOwner
Returns the frame to which the tooltip refers and is anchored.
owner = GameTooltip:GetOwner()
Returns:
ownerReference to the Frame object to which the tooltip is anchored (frame)
GetPadding
Returns the amount of space between tooltip’s text and its right-side edge.
padding = GameTooltip:GetPadding()
Returns:
paddingAmount of space between the right-side edge of the tooltip’s
text and the right-side edge of the tooltip frame (in pixels) (number)
1180 Part IV Reference
GetSpell
Returns information about the spell displayed in the tooltip.
spellName, spellRank, spellID = GameTooltip:GetSpell()
Returns:
spellNameName of the spell, or nil if the information in the tooltip is not for
a spell. (string)
spellRankSecondary text associated with the spell name (often a rank, e.g.
“Rank 8“)(string)
spellIDNumeric identifier for the spell and rank (number, spellID)
GetUnit
Returns information about the unit displayed in the tooltip.
name, unit = GameTooltip:GetUnit()
Returns:
nameName of the unit displayed in the tooltip, or nil (string)
unitUnit identifier of the unit, or nil if the unit cannot be referenced by a
unitID (string,unitID)
IsEquippedItem
Returns whether the tooltip is displaying an item currently equipped by the
player.
enabled = GameTooltip:IsEquippedItem()
Returns:
enabled1if the tooltip is displaying information about an item currently
equipped by the player; otherwise nil (1nil)
IsOwned
Returns whether the tooltip has an owner frame.
hasOwner = GameTooltip:IsOwned()
Returns:
hasOwner1if the tooltip has an owner frame; otherwise nil (1nil)
IsUnit
Returns whether the tooltip is displaying information for a given unit.
isUnit = GameTooltip:IsUnit(“unit“)
Arguments:
unit—A unit to query (string,unitID)
Returns:
isUnit1if the tooltip is displaying information for the unit; otherwise nil
(1nil)
NumLines
Returns the number of lines of text currently shown in the tooltip.
numLines = GameTooltip:NumLines()
Returns:
numLinesNumber of lines currently shown in the tooltip (number)
Chapter 29 Widget Reference 1181
SetAction
Fills the tooltip with information about the contents of an action slot.
GameTooltip:SetAction(slot)
Arguments:
slotAn action bar slot (number,actionID)
SetAnchorType
Sets the method for anchoring the tooltip relative to its owner.
GameTooltip:SetAnchorType(“anchor“ [, xOffset [, yOffset]])
Arguments:
anchorToken identifying the positioning method for the tooltip relative to its
owner frame (string)
ANCHOR_BOTTOMLEFT - Align the top right of the tooltip with the bottom left
of the owner
ANCHOR_CURSOR - Tooltip follows the mouse cursor
ANCHOR_LEFT - Align the bottom right of the tooltip with the top left of the
owner
ANCHOR_NONE - Tooltip appears in the default position
ANCHOR_PRESERVE - Tooltip’s position is saved between sessions (useful if the
tooltip is made user-movable)
ANCHOR_RIGHT - Align the bottom left of the tooltip with the top right of the
owner
ANCHOR_TOPLEFT - Align the bottom left of the tooltip with the top left of the
owner
ANCHOR_TOPRIGHT - Align the bottom right of the tooltip with the top right of
the owner
xOffset (optional)Horizontal distance from the anchor to the tooltip
(number)
yOffset (optional)Vertical distance from the anchor to the tooltip (number)
SetAuctionItem
Fills the tooltip with information about an item in the auction house.
GameTooltip:SetAuctionItem(“list“, index)
Arguments:
listType of auction listing (string, ah-list-type)
bidder - Auctions the player has bid on
list - Auctions the player can browse and bid on or buy out
owner - Auctions the player placed
indexIndex of an auction in the listing (number)
SetAuctionSellItem
Fills the tooltip with information about the item currently being set up for
auction.
GameTooltip:SetAuctionSellItem()
1182 Part IV Reference
SetBackpackToken
Fills the tooltip with information about a currency marked for watching on the
Backpack UI.
GameTooltip:SetBackpackToken(index)
Arguments:
indexIndex of a ‘slot’ for displaying currencies on the backpack (between 1
and MAX_WATCHED_TOKENS)(number)
SetBagItem
Fills the tooltip with information about an item in the player’s bags.
hasCooldown, repairCost = GameTooltip:SetBagItem(container, slot)
Arguments:
containerIndex of one of the player’s bags or other containers (number,con-
tainerID)
slotIndex of an item slot within the container (number, containerSlotID)
Returns:
hasCooldown1if the item is currently on cooldown, otherwise nil (number,
1nil)
repairCostCost of repairing the item (in copper, ignoring faction discounts)
(number)
SetBuybackItem
Fills the tooltip with information about item recently sold to a vendor and
available to be repurchased.
GameTooltip:SetBuybackItem(index)
Arguments:
indexIndex of an item in the buyback listing (between 1and
GetNumBuybackItems())(number)
SetCurrencyToken
Fills the tooltip with information about a special currency type.
GameTooltip:SetCurrencyToken(index)
Arguments:
indexIndex of a currency type in the currency list (between 1and
GetCurrencyListSize())(number)
SetEquipmentSet
Fills the tooltip with information about an equipment set.
GameTooltip:SetEquipmentSet(“name“)
Arguments:
nameName of the equipment set (string)
SetExistingSocketGem
Fills the tooltip with information about a permanently socketed gem.
GameTooltip:SetExistingSocketGem(index, toDestroy)
Chapter 29 Widget Reference 1183
Arguments:
indexIndex of a gem socket (between 1and GetNumSockets())(number)
toDestroyTrue to alter the tooltip display to indicate that this gem will be
destroyed by socketing a new gem; false to show the normal tooltip for the gem
(boolean)
SetFrameStack
Fills the tooltip with a list of frames under the mouse cursor.
GameTooltip:SetFrameStack(includeHidden)
Not relevant outside of addon development and debugging.
Arguments:
includeHiddenTrue to include hidden frames in the list; false to list only
visible frames (boolean)
SetGlyph
Fills the tooltip with information about one of the player’s glyphs.
GameTooltip:SetGlyph(socket, talentGroup)
Arguments:
socketWhich socket’s glyph to display (between 1and NUM_GLYPH_SLOTS)
(number,glyphIndex)
talentGroupWhich set of glyphs to display, if the player has Dual Talent
Specialization enabled (number)
1- Primary Talents
2-SecondaryTalents
nil - Currently active talents
SetGuildBankItem
Fills the tooltip with information about an item in the guild bank.
GameTooltip:SetGuildBankItem(tab, slot)
Information is only available if the guild bank tab has been opened in the
current play session.
Arguments:
tabIndex of a guild bank tab (between 1and GetNumGuildBank
Tabs())(number)
slotIndex of an item slot in the guild bank tab (between 1and
MAX_GUILDBANK_SLOTS_PER_TAB)(number)
SetHyperlink
Fills the tooltip with information about an item, quest, spell, or other entity
represented by a hyperlink.
GameTooltip:SetHyperlink(“hyperlink“)
Arguments:
hyperlinkA full hyperlink, or the linktype:linkdata portion thereof
(string, hyperlink)
1184 Part IV Reference
SetHyperlinkCompareItem
Fills the tooltip with information about the item currently equipped in the slot
used for the supplied item.
success = GameTooltip:SetHyperlinkCompareItem(“hyperlink“ [, index])
Arguments:
hyperlinkA full hyperlink, or the linktype:linkdata portion thereof, for
an item to compare against the player’s equipped similar item (string,hyper-
link)
index (optional)Index of the slot to compare against (1, 2, or 3), if more than
one item of the equipment type can be equipped at once (e.g. rings and trinkets)
(number)
Returns:
success1if an item’s information was loaded into the tooltip; otherwise nil
(number, 1nil)
SetInboxItem
Fills the tooltip with information about an item attached to a message in the
player’s inbox.
GameTooltip:SetInboxItem(mailID, attachmentIndex)
Arguments:
mailIDIndex of a message in the player’s inbox (between 1and
GetInboxNumItems())(number)
attachmentIndexIndex of an attachment to the message (between
1and select(8,GetInboxHeaderInfo(mailID)))(number)
SetInventoryItem
Fills the tooltip with information about an equipped item.
hasItem, hasCooldown, repairCost = i
GameTooltip:SetInventoryItem(“unit“, slot [, nameOnly])
Arguments:
unitA unit to query; only valid for ‘player’ or the unit currently being
inspected (string,unitID)
slotAn inventory slot number, as can be obtained from GetInventory
SlotInfo (number,inventoryID)
nameOnly (optional)True to omit much of the item’s information (stat
bonuses, sockets and binding) from the tooltip; false to show all of the item’s
information (boolean)
Returns:
hasItem1if the unit has an item in the given slot; otherwise nil (number,
1nil)
hasCooldown1if the item is currently on cooldown; otherwise nil (number,
1nil)
repairCostCost to repair the item (in copper, ignoring faction discounts)
(number)
Chapter 29 Widget Reference 1185
SetLootItem
Fills the tooltip with information about an item available as loot.
GameTooltip:SetLootItem(slot)
Arguments:
slotIndex of a loot slot (between 1and GetNumLootItems())(number)
SetLootRollItem
Fills the tooltip with information about an item currently up for loot rolling.
GameTooltip:SetLootRollItem(id)
Arguments:
idIndex of an item currently up for loot rolling (as provided in the
START_LOOT_ROLL event) (number)
SetMerchantCostItem
Fills the tooltip with information about an alternate currency required to
purchase an item from a vendor.
GameTooltip:SetMerchantCostItem(index, currency)
Only applies to item-based currencies, not honor or arena points.
Arguments:
indexIndex of an item in the vendor’s listing (between 1and
GetMerchantNumItems())(number)
currencyIndex of one of the item currencies required to purchase the item
(between 1and select(3,GetMerchantItemCostInfo(index)))(number)
SetMerchantItem
Fills the tooltip with information about an item available for purchase from a
vendor.
GameTooltip:SetMerchantItem(merchantIndex)
Arguments:
merchantIndexThe index of an item in the merchant window, between 1and
GetMerchantNumItems().(number)
SetMinimumWidth
Sets the minimum width of the tooltip.
GameTooltip:SetMinimumWidth(width)
Normally, a tooltip is automatically sized to match the width of its shortest line
of text; setting a minimum width can be useful if the tooltip also contains
non-text frames (such as an amount of money or a status bar).
The tooltip is not automatically resized to the new width; to do so, call the
tooltip’s :Show() method.
Arguments:
widthMinimum width of the tooltip frame (in pixels) (number)
1186 Part IV Reference
SetOwner
Sets the frame to which the tooltip refers and is anchored.
GameTooltip:SetOwner(frame [, “anchorType“ [, xOffset [, yOffset]]])
Arguments:
frameReference to the Frame to which the tooltip refers (frame)
anchorType (optional)Token identifying the positioning method for the
tooltip relative to its owner frame (string)
ANCHOR_BOTTOMLEFT - Align the top right of the tooltip with the bottom left
of the owner
ANCHOR_CURSOR - Tooltip follows the mouse cursor
ANCHOR_LEFT - Align the bottom right of the tooltip with the top left of the
owner
ANCHOR_NONE - Tooltip appears in the default position
ANCHOR_PRESERVE - Tooltip’s position is saved between sessions (useful if the
tooltip is made user-movable)
ANCHOR_RIGHT - Align the bottom left of the tooltip with the top right of the
owner
ANCHOR_TOPLEFT - Align the bottom left of the tooltip with the top left of the
owner
ANCHOR_TOPRIGHT - Align the bottom right of the tooltip with the top right of
the owner
xOffset (optional)The horizontal offset for the tooltip anchor
(number)
yOffset (optional)The vertical offset for the tooltip anchor (number)
SetPadding
Sets the amount of space between tooltip’s text and its right-side edge.
GameTooltip:SetPadding(padding)
Used in the default UI’s ItemRefTooltip to provide space for a close
button.
Arguments:
paddingAmount of space between the right-side edge of the tooltip’s
text and the right-side edge of the tooltip frame (in pixels) (number)
SetPetAction
Fills the tooltip with information about a pet action.
GameTooltip:SetPetAction(index)
Only provides information for pet action slots containing pet spellsin the
default UI, the standard pet actions (attack, follow, passive, aggressive, etc) are
special-cased to show specific tooltip text.
Arguments:
indexIndex of a pet action button (between 1and NUM_PET_ACTION_
SLOTS)(number)
Chapter 29 Widget Reference 1187
SetPossession
Fills the tooltip with information about one of the special actions available
while the player possesses another unit.
GameTooltip:SetPossession(index)
Arguments:
indexIndex of a possession bar action (between 1and NUM_POSSESS_SLOTS)
(number)
SetQuestItem
Fills the tooltip with information about an item in a questgiver dialog.
GameTooltip:SetQuestItem(“itemType“, index)
Arguments:
itemTypeToken identifying one of the possible sets of items (string)
choice - Items from which the player may choose a reward
required - Items required to complete the quest
reward - Items given as reward for the quest
indexIndex of an item in the set (between 1and GetNumQuest
Choices(),GetNumQuestItems(),orGetNumQuestRewards(), according to
itemType)(number)
SetQuestLogItem
Fills the tooltip with information about an item related to the selected quest in
the quest log.
GameTooltip:SetQuestLogItem(“itemType“, index)
Arguments:
itemTypeToken identifying one of the possible sets of items (string)
choice - Items from which the player may choose a reward
reward - Items always given as reward for the quest
indexIndex of an item in the set (between 1and GetNumQuestLog
Choices() or GetNumQuestLogRewards(), according to itemType)(number)
SetQuestLogRewardSpell
Fills the tooltip with information about the reward spell for the selected quest
in the quest log.
GameTooltip:SetQuestLogRewardSpell()
SetQuestLogSpecialItem
Fills the tooltip with information about a usable item associated with a current
quest.
GameTooltip:SetQuestLogSpecialItem(questIndex)
Arguments:
questIndexIndex of a quest log entry with an associated usable
item (between 1and GetNumQuestLogEntries())(number)
1188 Part IV Reference
SetQuestRewardSpell
Fills the tooltip with information about the spell reward in a questgiver dialog.
GameTooltip:SetQuestRewardSpell()
SetSendMailItem
Fills the tooltip with information about an item attached to the outgoing mail
message.
GameTooltip:SetSendMailItem(slot)
Arguments:
slotIndex of an outgoing attachment slot (between 1and ATTACHMENTS_
MAX_SEND)(number)
SetShapeshift
Fills the tooltip with information about an ability on the stance/shapeshift bar.
GameTooltip:SetShapeshift(index)
Arguments:
indexIndex of an ability on the stance/shapeshift bar (between 1and
GetNumShapeshiftForms())(number)
SetSocketGem
Fills the tooltip with information about a gem added to a socket.
GameTooltip:SetSocketGem(index)
Arguments:
indexIndex of a gem socket (between 1and GetNumSockets())(number)
SetSocketedItem
Fills the tooltip with information about the item currently being
socketed.
GameTooltip:SetSocketedItem()
SetSpell
Fills the tooltip with information about a spell from the player (or pet’s)
spellbook.
GameTooltip:SetSpell(id, “bookType“)
Arguments:
idIndex of a spell in the spellbook (number, spellbookID)
bookTypeType of spellbook (string)
pet - The pet’s spellbook
spell - The player’s spellbook
SetSpellByID
Fills the tooltip with information about a spell specified by ID.
GameTooltip:SetSpellByID(id)
Arguments:
idNumeric ID of a spell (number, spellID)
Chapter 29 Widget Reference 1189
SetTalent
Fills the tooltip with information about a talent.
GameTooltip:SetTalent(tabIndex, talentIndex, inspect, pet, talentGroup)
Arguments:
tabIndexIndex of a talent tab (between 1and GetNumTalentTabs())
(number)
talentIndexIndex of a talent option (between 1and GetNum
Talents())(number)
inspecttrue to return information for the currently inspected
unit; false to return information for the player (boolean)
pettrue to return information for the player’s pet; false to return informa-
tion for the player (boolean)
talentGroupWhich set of talents to edit, if the player has Dual Talent Special-
ization enabled (number)
1- Primary Talents
2-SecondaryTalents
nil - Currently active talents
SetText
Sets the tooltip’s text.
GameTooltip:SetText(“text“ [, r [, g [, b [, a]]]])
Any other content currently displayed in the tooltip will be removed or
hidden, and the tooltip’s size will be adjusted to fit the new text.
Arguments:
textText to be displayed in the tooltip (string)
r(optional)Red component of the text color (0.0 - 1.0) (number)
g(optional)Green component of the text color (0.0 - 1.0) (number)
b(optional)Blue component of the text color (0.0 - 1.0) (number)
a(optional)Alpha (opacity) for the text (0.0 =fully transparent, 1.0 =fully
opaque) (number)
SetTotem
Fills the tooltip with information about one of the player’s active totems.
GameTooltip:SetTotem(slot)
Totem functions are also used for ghouls summoned by a Death Knight’s Raise
Dead ability (if the ghoul is not made a controllable pet by the Master of
Ghouls talent).
Arguments:
slotWhich totem to query (number)
1- Fire (or Death Knight’s ghoul)
2-Earth
3-Water
4-Air
1190 Part IV Reference
SetTracking
Fills the tooltip with information about the currently selected tracking type.
GameTooltip:SetTracking()
If no tracking type is selected, the tooltip reads ‘‘Click to choose tracking type’’
(or localized equivalent).
SetTradePlayerItem
Fills the tooltip with information about an item offered for trade by the player.
GameTooltip:SetTradePlayerItem(index)
See :SetTradeTargetItem() for items to be received from the trade.
Arguments:
indexIndex of an item offered for trade by the player (between 1and
MAX_TRADE_ITEMS)(number)
SetTradeSkillItem
Fills the tooltip with information about an item created by a trade skill recipe
or a reagent in the recipe.
GameTooltip:SetTradeSkillItem(skillIndex [, reagentIndex])
Arguments:
skillIndexIndex of a recipe in the trade skill list (between 1and
GetNumTradeSkills())(number)
reagentIndex (optional)Index of a reagent in the recipe (between 1and
GetTradeSkillNumReagents()); if omitted, displays a tooltip for the item cre-
ated by the recipe (number)
SetTradeTargetItem
Fills the tooltip with information about an item offered for trade by the target.
GameTooltip:SetTradeTargetItem(index)
See :SetTradePlayerItem() for items to be traded away by the player.
Arguments:
indexIndex of an item offered for trade by the target (between 1and
MAX_TRADE_ITEMS)(number)
SetTrainerService
Fills the tooltip with information about a trainer service.
GameTooltip:SetTrainerService(index)
Arguments:
indexIndex of an entry in the trainer service listing (between 1and
GetNumTrainerServices())(number)
SetUnit
Fills the tooltip with information about a unit.
GameTooltip:SetUnit(“unit“)
Arguments:
unit—A unit to query (string,unitid)
Chapter 29 Widget Reference 1191
SetUnitAura
Fills the tooltip with information about a buff or debuff on a unit.
GameTooltip:SetUnitAura(“unit“, index [, “filter“])
Arguments:
unit—A unit to query (string,unitID)
indexIndex of a buff or debuff on the unit (number)
filter (optional)A list of filters to use when resolving the index, separated
by the pipe ‘|’character;e.g.“RAID|PLAYER“ will query group buffs cast by the
player (string)
CANCELABLE - Show auras that can be cancelled
HARMFUL - Show debuffs only
HELPFUL - Show buffs only
NOT_CANCELABLE - Show auras that cannot be cancelled
PLAYER - Show auras the player has cast
RAID - Show auras the player can cast on party/raid members (as opposed to
self buffs)
SetUnitBuff
Fills the tooltip with information about a buff on a unit.
GameTooltip:SetUnitBuff(“unit“, index [, “filter“])
This method is an alias for :SetUnitAura() with a built-in HELPFUL filter
(which cannot be removed or negated with the HARMFUL
filter).
Arguments:
unit—A unit to query (string,unitID)
indexIndex of a buff or debuff on the unit (number)
filter (optional)A list of filters to use when resolving the index, separated
by the pipe ‘|’character;e.g.“RAID|PLAYER“ will query group buffs cast by the
player (string)
CANCELABLE - Show auras that can be cancelled
NOT_CANCELABLE - Show auras that cannot be cancelled
PLAYER - Show auras the player has cast
RAID - Show auras the player can cast on party/raid members (as opposed to
self buffs)
SetUnitDebuff
Fills the tooltip with information about a debuff on a unit.
GameTooltip:SetUnitDebuff(“unit“, index [, “filter“])
This method is an alias for :SetUnitAura() with a built-in HARMFUL filter
(which cannot be removed or negated with the HELPFUL filter).
Arguments:
unit—A unit to query (string,unitID)
1192 Part IV Reference
indexIndex of a buff or debuff on the unit (number)
filter (optional)A list of filters to use when resolving the index, separated by
thepipe‘|’character;e.g.“CANCELABLE|PLAYER“ will query cancelable debuffs
cast by the player (string)
CANCELABLE - Show auras that can be cancelled
NOT_CANCELABLE - Show auras that cannot be cancelled
PLAYER - Show auras the player has cast
RAID - Show auras the player can cast on party/raid members (as opposed to
self buffs)
Minimap
Minimap is a frame type whose backdrop is filled in with a top-down representation of
the area around the character being played. You can have more than one if you are so
inclined, but they can’t have different coordinates or locations, and tracking blips do
not work correctly unless they’re the exact same size. You can use methods to control
the textures that are used by the minimap to display different elements such as group
members or arrows to nearby points of interest, but you cannot determine where these
things are. You can also adjust the zoom on a Minimap or determine where it is being
pinged by you or another member of your group.
The stock UI uses a Minimap only once, predictably for the minimap in the upper
right, but some mods will move it or create a larger, fainter version to use as a
‘‘heads-up display.’’
Minimap has all the methods from Frame, plus the following:
GetPingPosition
Returns the location of the last ‘‘ping’’ on the minimap.
x, y = Minimap:GetPingPosition()
Coordinates are pixel distances relative to the center of the minimap (not
fractions of the minimap’s size as with :GetPingPosition()); positive
coordinates are above or to the right of the center, negative are below or to the
left.
Returns:
xHorizontal coordinate of the ‘‘ping’’ position (number)
yVertical coordinate of the ‘‘ping’’ position (number)
GetZoom
Returns the minimap’s current zoom level.
zoomLevel = Minimap:GetZoom()
Returns:
zoomLevelIndex of the current zoom level (between 0 for the widest possible
zoom and (minimap:GetZoomLevels() - 1) for the narrowest possible zoom)
(number)
Chapter 29 Widget Reference 1193
GetZoomLevels
Returns the number of available zoom settings for the minimap.
zoomLevels = Minimap:GetZoomLevels()
Returns:
zoomLevelsNumber of available zoom settings for the minimap (number)
PingLocation
’’Pings’’ the minimap at a given location.
Minimap:PingLocation(x, y)
Coordinates are pixel distances relative to the center of the minimap (not
fractionsoftheminimapssizeaswith:GetPingPosition()); positive
coordinates are above or to the right of the center, negative are below or to the
left.
Arguments:
xHorizontal coordinate of the ‘‘ping’’ position (in pixels) (number)
yVertical coordinate of the ‘‘ping’’ position (in pixels) (number)
SetBlipTexture
Sets the texture used to display quest and tracking icons on the minimap.
Minimap:SetBlipTexture(“filename“)
The replacement texture must match the specifications of the default texture
(Interface\\Minimap\\ObjectIcons): 256 pixels wide by 64 pixels tall,
containing an 8x2 grid of icons each 32x32 pixels square.
Arguments:
filenamePath to a texture containing display quest and tracking icons for the
minimap (string)
SetClassBlipTexture
Sets the texture used to display party and raid members on the
minimap.
Minimap:SetClassBlipTexture(“filename“)
Usefulness of this method to addons is limited, as the replacement texture
must match the specifications of the default texture
(Interface\\Minimap\\PartyRaidBlips): 256 pixels wide by 128 pixels
tall, containing an 8x4 grid of icons each 32x32 pixels square.
Arguments:
filenamePath to a texture containing icons for party and raid members
(string)
SetCorpsePOIArrowTexture
Sets the texture used to the player’s corpse when located beyond the scope of
the minimap.
Minimap:SetCorpsePOIArrowTexture(“filename“)
1194 Part IV Reference
The default texture is Interface\\Minimap\\ROTATING-
MINIMAPCORPSEARROW.
Arguments:
filename—Path to a texture image (string)
SetIconTexture
Sets the texture used to display various points of interest on the minimap.
Minimap:SetIconTexture(“filename“)
Usefulness of this method to addons is limited, as the replacement texture
must match the specifications of the default texture
(Interface\\Minimap\\POIIcons): a 256x256 pixel square containing a
16x16 grid of icons each 16x16 pixels square.
Arguments:
filenamePath to a texture containing icons for various map landmarks
(string)
SetMaskTexture
Sets the texture used to mask the shape of the minimap.
Minimap:SetMaskTexture(“filename“)
White areas in the texture define where the dynamically drawn minimap is
visible. The default mask (Textures\\MinimapMask) is circular; a texture
image consisting of an all-white square will result in a square minimap.
Arguments:
filenamePath to a texture used to mask the shape of the minimap (string)
SetPOIArrowTexture
Sets the texture used to represent points of interest located beyond the scope of
the minimap.
Minimap:SetPOIArrowTexture(“filename“)
This texture is used for points of interest such as those which appear when
asking a city guard for directions. The default texture is
Interface\Minimap\ROTATING-MINIMAPGUIDEARROW.
Arguments:
filename—Path to a texture image (string)
SetPlayerTexture
Sets the texture used to represent the player on the minimap.
Minimap:SetPlayerTexture(“filename“)
The default texture is Interface\Minimap\MinimapArrow.
Arguments:
filename—Path to a texture image (string)
SetPlayerTextureHeight
Sets the height of the texture used to represent the player on the minimap.
Minimap:SetPlayerTextureHeight(height)
Chapter 29 Widget Reference 1195
Arguments:
heightHeight of the texture used to represent the player on the minimap
(number)
SetPlayerTextureWidth
Sets the width of the texture used to represent the player on the minimap.
Minimap:SetPlayerTextureWidth(width)
Arguments:
widthWidth of the texture used to represent the player on the minimap
(number)
SetStaticPOIArrowTexture
Sets the texture used to represent static points of interest located beyond the
scope of the minimap.
Minimap:SetStaticPOIArrowTexture(“filename“)
This texture is used for static points of interest such as nearby towns and cities.
The default texture is Interface\\Minimap\\ROTATING-
MINIMAPARROW.
Arguments:
filename—Path to a texture image (string)
SetZoom
Sets the minimap’s zoom level.
Minimap:SetZoom(zoomLevel)
Arguments:
zoomLevelIndex of a zoom level (between 0 for the widest possible zoom
and (minimap:GetZoomLevels() - 1) for the narrowest possible zoom)
(number)
Model
When you want to display a rendering of a three-dimensional object as part of the UI, a
Model frame is your basic tool. These frames provide a rendering environment which
is drawn into the backdrop of their frame, allowing you to display the contents of an
.m2 file and set facing, scale, light and fog information, or run motions associated with
the model.
It’s comparatively rare to see the basic Model type used; most renderings of models
in the stock UI and mods use PlayerFrame to display players, pets and mounts.
Model has all the methods from Frame, plus the following:
AdvanceTime
Advances to the model’s next animation frame.
Model:AdvanceTime()
(Applies to 3D animations defined within the model file, not UI Animations.)
1196 Part IV Reference
ClearFog
Disables fog display for the model.
Model:ClearFog()
ClearModel
Removes the 3D model currently displayed.
Model:ClearModel()
GetFacing
Returns the model’s current rotation setting.
facing = Model:GetFacing()
The 3D model displayed by the model object can be rotated about its vertical
axis. For example, a model of a player race faces towards the viewer when its
facing is set to 0; setting facing to math.pi faces it away from the viewer.
Returns:
facingCurrent rotation angle of the model (in radians) (number)
GetFogColor
Returns the model’s current fog color.
red, green, blue = Model:GetFogColor()
Does not indicate whether fog display is enabled.
Returns:
redRed component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
blueBlue component of the color (0.0 - 1.0) (number)
GetFogFar
Returns the far clipping distance for the model’s fog.
distance = Model:GetFogFar()
This determines how far from the camera the fog ends.
Returns:
distanceThe distance to the fog far clipping plane (number)
GetFogNear
Returns the near clipping distance for the model’s fog.
distance = Model:GetFogNear()
This determines how close to the camera the fog begins.
Returns:
distanceThe distance to the fog near clipping plane (number)
GetLight
Returns properties of the light sources used when rendering the model.
enabled, omni, dirX, dirY, dirZ, ambIntensity, ambR, ambG, ambB, i
dirIntensity, dirR, dirG, dirB = Model:GetLight()
Chapter 29 Widget Reference 1197
Returns:
enabled1if lighting is enabled; otherwise nil (1nil)
omni1if omnidirectional lighting is enabled; otherwise 0(number)
dirXCoordinate of the directional light in the axis perpendicular to the screen
(negative values place the light in front of the model, positive values behind)
(number)
dirYCoordinate of the directional light in the horizontal axis (negative values
place the light to the left of the model, positive values to the right) (number)
dirZCoordinate of the directional light in the vertical axis (negative
values place the light below the model, positive values above (number)
ambIntensityIntensity of the ambient light (0.0 - 1.0) (number)
ambR (optional)Red component of the ambient light color (0.0 - 1.0); omitted if
ambIntensity is 0 (number)
ambG (optional)Green component of the ambient light color (0.0 - 1.0); omitted
if ambIntensity is 0 (number)
ambB (optional)Blue component of the ambient light color (0.0 - 1.0); omitted if
ambIntensity is 0 (number)
dirIntensity (optional)Intensity of the directional light (0.0 - 1.0) (number)
dirR (optional)Red component of the directional light color (0.0 - 1.0); omitted
if dirIntensity is 0 (number)
dirG (optional)Green component of the directional light color (0.0 - 1.0); omit-
ted if dirIntensity is 0 (number)
dirB (optional)Blue component of the directional light color (0.0 - 1.0); omit-
ted if dirIntensity is 0 (number)
GetModel
Returns the model file currently displayed.
filename = Model:GetModel()
May instead return a reference to the Model object itself if a filename is not
available.
Returns:
filenamePath to the model file currently displayed (string)
GetModelScale
Returns the scale factor determining the size at which the 3D model appears.
scale = Model:GetModelScale()
Returns:
scaleScale factor determining the size at which the 3D model appears
(number)
GetPosition
Returns the position of the 3D model within the frame.
x, y, z = Model:GetPosition()
1198 Part IV Reference
Returns:
xPosition of the model on the axis perpendicular to the plane of the screen
(positive values make the model appear closer to the viewer; negative values
place it further away) (number)
yPosition of the model on the horizontal axis (positive values place the model
to the right of its default position; negative values place it to the left) (number)
zPosition of the model on the vertical axis (positive values place
the model above its default position; negative values place it below)
(number)
ReplaceIconTexture
Sets the icon texture used by the model.
Model:ReplaceIconTexture(“filename“)
Only affects models that use icons (e.g. the model producing the default UI’s
animation which appears when an item goes into a bag).
Arguments:
filenamePathtoanicontextureforuseinthemodel(string)
SetCamera
Sets the view angle on the model to a pre-defined camera location.
Model:SetCamera(index)
Camera view angles are defined within the model files and not otherwise
available to the scripting system. Some camera indices are standard across
most models:
0- Non-movable camera, focused on the unit’s face (if applicable);
used by the game engine when rendering portrait textures
1- Movable camera, showing the entire body of the unit
2or higher - Movable camera in default position
Arguments:
indexIndex of a camera view defined by the model file (number)
SetFacing
Sets the model’s current rotation.
Model:SetFacing(facing)
The 3D model displayed by the model object can be rotated about its vertical
axis. For example, if the model faces towards the viewer when its facing is set
to 0, setting facing to math.pi faces it away from the viewer.
Arguments:
facingRotation angle for the model (in radians) (number)
SetFogColor
Sets the model’s fog color, enabling fog display if disabled.
Model:SetFogColor(red, green, blue)
Chapter 29 Widget Reference 1199
Arguments:
redRed component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
blueBlue component of the color (0.0 - 1.0) (number)
SetFogFar
Sets the far clipping distance for the model’s fog.
Model:SetFogFar(distance)
This sets how far from the camera the fog ends.
Arguments:
distanceThe distance to the fog far clipping plane (number)
SetFogNear
Sets the near clipping distance for the model’s fog.
Model:SetFogNear(distance)
This sets how close to the camera the fog begins.
Arguments:
distanceThe distance to the fog near clipping plane (number)
SetGlow
Sets the model’s glow amount.
Model:SetGlow(amount)
Arguments:
amountGlowamountforthemodel(number)
SetLight
Sets properties of the light sources used when rendering the model.
Model:SetLight(enabled, omni, dirX, dirY, dirZ, ambIntensity i
[, ambR [, ambG [, ambB [, dirIntensity [, dirR [, dirG [, dirB]]]]]]])
Arguments:
enabled1if lighting is enabled; otherwise nil (1nil)
omni1if omnidirectional lighting is enabled; otherwise 0(number)
dirXCoordinate of the directional light in the axis perpendicular to the screen
(negative values place the light in front of the model, positive values behind)
(number)
dirYCoordinate of the directional light in the horizontal axis (negative values
place the light to the left of the model, positive values to the right) (number)
dirZCoordinate of the directional light in the vertical axis
(negative values place the light below the model, positive values above (number)
ambIntensityIntensity of the ambient light (0.0 - 1.0) (number)
ambR (optional)Red component of the ambient light color (0.0 - 1.0); omitted if
ambIntensity is 0 (number)
ambG (optional)Green component of the ambient light color (0.0 - 1.0); omitted
if ambIntensity is 0 (number)
1200 Part IV Reference
ambB (optional)Blue component of the ambient light color (0.0 - 1.0); omitted if
ambIntensity is 0 (number)
dirIntensity (optional)Intensity of the directional light (0.0 - 1.0) (number)
dirR (optional)Red component of the directional light color (0.0 - 1.0); omitted
if dirIntensity is 0 (number)
dirG (optional)Green component of the directional light color (0.0 - 1.0); omit-
ted if dirIntensity is 0 (number)
dirB (optional)Blue component of the directional light color (0.0 - 1.0); omit-
ted if dirIntensity is 0 (number)
SetModel
Sets the model file to be displayed.
Model:SetModel(“filename“)
Arguments:
filenamePath to the model file to be displayed (string)
SetModelScale
Sets the scale factor determining the size at which the 3D model appears.
Model:SetModelScale(scale)
Arguments:
scaleScale factor determining the size at which the 3D model appears
(number)
SetPosition
Returns the position of the 3D model within the frame.
Model:SetPosition(x, y, z)
Arguments:
xPosition of the model on the axis perpendicular to the plane of the screen
(positive values make the model appear closer to the viewer; negative values
place it further away) (number)
yPosition of the model on the horizontal axis (positive values place the model
to the right of its default position; negative values place it to the left) (number)
zPosition of the model on the vertical axis (positive values place the
model above its default position; negative values place it below) (number)
SetSequence
Sets the animation sequence to be used by the model.
Model:SetSequence(sequence)
The number of available sequences and behavior of each are defined within the
model files and not available to the scripting system.
Arguments:
sequenceIndex of an animation sequence defined by the model file (number)
SetSequenceTime
Sets the animation sequence and time index to be used by the model.
Model:SetSequenceTime(sequence, time)
Chapter 29 Widget Reference 1201
The number of available sequences and behavior of each are defined within the
model files and not available to the scripting system.
Arguments:
sequenceIndex of an animation sequence defined by the model file (number)
timeTime index within the sequence (number)
PlayerModel
PlayerModels are the most commonly used subtype of Model frame. They expand on
the Model type by adding functions to quickly set the model to represent a particular
player or creature, by unitID or creature ID.
These models are used by the stock UI for ‘‘paper doll’’ frames, to display a player’s
character, minion, vanity pets and mounts. They’re also used by unit frame mods,
to provide animated portraits or full-body ‘‘action figure’’ displays of characters and
monsters.
PlayerModel has all the methods from Model, plus the following:
RefreshUnit
Updates the model’s appearance to match that of its unit.
PlayerModel:RefreshUnit()
Used in the default UI’s inspect window when the player’s target changes
(changing the model to match the ‘‘new appearance’’ of the unit “target“)or
when the UNIT_MODEL_CHANGED event fires for the inspected unit (updating
the model’s appearance to reflect changes in the unit’s equipment or shapeshift
form).
SetCreature
Sets the model to display the 3D model of a specific creature.
PlayerModel:SetCreature(creature)
Used in the default UI to set the model used for previewing non-combat pets
and mounts (see GetCompanionInfo()), but can also be used to display the
model for any creature whose data is cached by the client. Creature IDs can
commonly be found on database sites (e.g. creature ID #10181).
Arguments:
creatureNumeric ID of a creature (number)
SetRotation
Sets the model’s current rotation by animating the model.
PlayerModel:SetRotation(facing)
This method is similar to Model:SetFacing() in that it rotates the 3D model
displayed about its vertical axis; however, since the PlayerModel object
displays a unit’s model, this method is provided to allow for animating the
rotation using the model’s built-in animations for turning right and left.
1202 Part IV Reference
For example, if the model faces towards the viewer when its facing is set to 0,
setting its facing to math.pi faces it away from the viewer.
Arguments:
facingRotation angle for the model (in radians) (number)
SetUnit
Sets the model to display the 3D model of a specific unit.
PlayerModel:SetUnit(“unit“)
Arguments:
unitUnit ID of a visible unit (string,unitID)
DressUpModel
The DressUpModel type was added to provide support for the ‘‘dressing room’’
functionality when it was introduced. This model can be set to a particular unit, and
then given different pieces of gear to display on that unit with the TryOn function.
It also provides an Undress feature which can be used to view how your character’s
gear will look without concealing articles such as a cloak or tabard that you might be
wearing.
DressUpModel has all the methods from PlayerModel, plus the following:
Dress
Updates the model to reflect the character’s currently equipped items.
DressUpModel:Dress()
TryOn
Updates the model to reflect the character’s appearance after equipping a
specific item.
DressUpModel:TryOn(itemID) or DressUpModel:TryOn(“itemName“) or i
DressUpModel:TryOn(“itemLink“)
Arguments:
itemID—An items ID (number)
itemName—An items name (string)
itemLinkAn item’s hyperlink, or any string containing the itemString por-
tion of an item link (string)
Undress
Updates the model to reflect the character’s appearance without any equipped
items.
DressUpModel:Undress()
TabardModel
TabardModel is a frame type provided specifically for designing or modifying guild
tabards. It provides functions for displaying a character in a sample tabard and cycling
Chapter 29 Widget Reference 1203
through different trim textures, emblems and color schemes, as well as saving the
selected look as your guild’s current tabard (this requires that your character have
appropriate guild privileges to do so).
Because the stock UI already includes a fairly comprehensive tabard interface using
one of these frames, it’s fairly unlikely that you’ll need to create one of your own.
TabardModel has all the methods from PlayerModel, plus the following:
CanSaveTabardNow
Returns whether the tabard model’s current design can be saved as the player’s
guild tabard.
enabled = TabardModel:CanSaveTabardNow()
Returns:
enabled1if the tabard model’s current design can be saved as the player’s
guild tabard; otherwise nil (1nil)
CycleVariation
Cycles through available design variations for the tabard model.
TabardModel:CycleVariation(variable, delta)
Arguments:
variableNumber identifying one of the five tabard design variables:
(number)
1-Icon
2- Icon color
3-Borderstyle
4- Border color
5- Background color
deltaNumber of steps by which to cycle through available options for the
design variable (e.g. 1for next design, -1 for previous design, 3to skip ahead by
three) (number)
GetLowerBackgroundFileName
Returns the image file for the lower portion of the tabard model’s current
background design.
TabardModel:GetLowerBackgroundFileName(“filename“)
Arguments:
filenamePath to the texture image file for the lower portion
of the tabard model’s current background design (string)
GetLowerEmblemFileName
Returns the image file for the lower portion of the tabard model’s current
emblem design.
TabardModel:GetLowerEmblemFileName(“filename“)
Arguments:
filenamePath to the texture image file for the lower portion of the tabard
model’s current emblem design (string)
1204 Part IV Reference
GetLowerEmblemTexture
Sets a Texture object to display the lower portion of the tabard model’s
current emblem design.
TabardModel:GetLowerEmblemTexture(texture)
Arguments:
textureReference to a Texture object (texture)
GetUpperBackgroundFileName
Returns the image file for the upper portion of the tabard model’s current
background design.
TabardModel:GetUpperBackgroundFileName(“filename“)
Arguments:
filenamePath to the texture image file for the upper portion
of the tabard model’s current background design (string)
GetUpperEmblemFileName
Returns the image file for the upper portion of the tabard model’s current
emblem design.
TabardModel:GetUpperEmblemFileName(“filename“)
Arguments:
filenamePath to the texture image file for the upper portion of the tabard
model’s current emblem design (string)
GetUpperEmblemTexture
Sets a Texture object to display the upper portion of the tabard model’s
current emblem design.
TabardModel:GetUpperEmblemTexture(texture)
Arguments:
textureReference to a Texture object (texture)
InitializeTabardColors
Sets the tabard model’s design to match the player’s guild tabard.
TabardModel:InitializeTabardColors()
If the player is not in a guild or the player’s guild does not yet have a tabard
design, randomizes the tabard model’s design.
Save
Saves the current tabard model design as the player’s guild tabard.
TabardModel:Save()
Has no effect if the player is not a guild leader.
MovieFrame
MovieFrame is one of the least well-known frame subtypes. To date, it has been used in
only one well-known mod, which was an April Fools’ Day joke, HighRoller. If you’re
Chapter 29 Widget Reference 1205
curious what this mod did, it’s still available for download; read the description or try
and run it (but keep in mind it’s a prank.) It runs the contents of an .avi file, for there
are some fairly stringent requirements on the file format supplied.
MovieFrame has all the methods from Frame, plus the following:
EnableSubtitles
Enables or disables subtitles for movies played in the frame.
MovieFrame:EnableSubtitles(enable)
Subtitles are not automatically displayed by the MovieFrame; enabling
subtitles causes the frame’s OnMovieShowSubtitle and
OnMovieHideSubtitle script handlers to be run when subtitle text should be
displayed.
Arguments:
enableTrue to enable display of movie subtitles; false to disable (boolean)
StartMovie
Plays a specified movie in the frame.
enabled = MovieFrame:StartMovie(“filename“, volume)
Note: Size and position of the movie display is unaffected by that of the
MovieFramemovies are automatically centered and sized proportionally to
fill the screen in their largest dimension (i.e. a widescreen movie will fill the
width of the screen but not necessarily its full height).
Arguments:
filenamePath to a movie file (excluding filename extension) (string)
volumeAudio volume for movie playback (0 =minimum, 255 =maximum)
(number)
Returns:
enabled1if a valid movie was loaded and playback begun; otherwise nil
(1nil)
Example:
-- create a MovieFrame and play the Blizzard logo intro movie
-- bundled with the game
CreateFrame(“MovieFrame“,“MiniMovie“,UIParent)
MiniMovie:StartMovie(“Interface\\Cinematics\\Logo_1024“,255)
-- play a XviD-encoded AVI movie bundled with an addon
MiniMovie:StartMovie(“Interface\\AddOns\\MyAddon\\MyMovie“,255)
StopMovie
Stops the movie currently playing in the frame.
MovieFrame:StopMovie()
1206 Part IV Reference
ScrollFrame
ScrollFrame is how a large body of content can be displayed through a small window.
The ScrollFrame is the size of the ‘‘window’’ through which you want to see the larger
content, and it has another frame set as a ‘‘ScrollChild’’ containing the full content.
The proportion by which the ScrollChild is larger than the ScrollFrame automatically
determines the horizontal and vertical scroll range of the ScrollFrame. You can get
these ranges or position the ScrollChild ‘‘behind’’ the ScrollFrame within those ranges
using ScrollFrame’s methods. It also allows you to set a new frame as the ScrollChild.
When a ScrollFrame is used for repetitive content, such as the buttons for assign-
ing key bindings or the friends in your social frame, it is often implemented as a
‘‘FauxScrollFrame,’’ which contains enough of these subframes in the ScrollChild to
fill the ScrollFrame, plus one. It then saves an offset and maps which of the elements
in an internal list are displayed.
To create a ScrollFrame’s ScrollChild in XML, include a <ScrollChild> element
as a direct child of the <ScrollFrame> element. The <ScrollChild> element should
have one child, of any type descended from <Frame>. To create the scroll child in Lua,
create the frame using CreateFrame(), and then attach the child to the scroll frame
using ScrollFrame:SetScrollChild(child). The child frame must always have
an absolute size set with <AbsDimension> in XML or using both SetWidth() and
SetHeight() in Lua.
A ScrollFrame does not automatically include an element that sets the scroll range.
Typically, you add a Slider as a child of a ScrollFrame, with an OnValueChanged
handler that sets the scroll value.
ScrollFrames are common throughout the UI, used for quest text, readable items,
lists of friends and guild members, and similar applications.
ScrollFrame has all the methods from Frame, plus the following:
GetHorizontalScroll
Returns the scroll frame’s current horizontal scroll
position.
scroll = ScrollFrame:GetHorizontalScroll()
Returns:
scrollCurrent horizontal scroll position (0 =at left edge, frame:Get
HorizontalScrollRange() =at right edge) (number)
GetHorizontalScrollRange
Returns the scroll frame’s maximum horizontal (rightmost) scroll position.
maxScroll = ScrollFrame:GetHorizontalScrollRange()
Returns:
maxScrollMaximum horizontal scroll position (representing the right edge
of the scrolled area) (number)
GetScrollChild
Returns the frame scrolled by the scroll frame.
scrollChild = ScrollFrame:GetScrollChild()
Chapter 29 Widget Reference 1207
Returns:
scrollChildReference to the Frame object scrolled by the scroll frame
(frame)
GetVerticalScroll
Returns the scroll frame’s current vertical scroll position.
scroll = ScrollFrame:GetVerticalScroll()
Returns:
scrollCurrent vertical scroll position (0 =at top edge, frame:Get
VerticalScrollRange() =at bottom edge) (number)
GetVerticalScrollRange
Returns the scroll frame’s maximum vertical (bottom) scroll position.
maxScroll = ScrollFrame:GetVerticalScrollRange()
Returns:
maxScrollMaximum vertical scroll position (representing the bottom edge of
the scrolled area) (number)
SetHorizontalScroll
Sets the scroll frame’s horizontal scroll position.
ScrollFrame:SetHorizontalScroll(scroll)
Arguments:
scrollCurrent horizontal scroll position (0 =at left edge, frame:Get
HorizontalScrollRange() =at right edge) (number)
SetScrollChild
Sets the scroll child for the scroll frame.
ScrollFrame:SetScrollChild(frame)
The scroll child frame represents the (generally larger) area into which the
scroll frame provides a (generally smaller) movable ‘‘window’’. The child must
have an absolute size, set either by <AbsDimension> in XML or using both
SetWidth() and SetHeight() in Lua.
Setting a frame’s scroll child involves changing the child frame’s parentthus,
if the frame’s scroll child is protected, this operation cannot be performed
while in combat.
Arguments:
frameReference to another frame to be the ScrollFrame’s child.
(frame)
SetVerticalScroll
Sets the scroll frame’s vertical scroll position.
ScrollFrame:SetVerticalScroll(scroll)
Arguments:
scrollCurrent vertical scroll position (0 =at top edge, frame:Get
VerticalScrollRange() =at bottom edge) (number)
1208 Part IV Reference
UpdateScrollChildRect
Updates the position of the scroll frame’s child.
ScrollFrame:UpdateScrollChildRect()
The ScrollFrame automatically adjusts the position of the child frame when
scrolled, but manually updating its position may be necessary when changing
the size or contents of the child frame.
SimpleHTML
The most sophisticated control over text display is offered by SimpleHTML widgets.
When its text is set to a string containing valid HTML markup, a SimpleHTML
widget will parse the content into its various blocks and sections, and lay the text
out. While it supports most common text commands, a SimpleHTML widget accepts
an additional argument to most of these; if provided, the element argument will
specify the HTML elements to which the new style information should apply, such as
formattedText:SetTextColor(“h2“, 1, 0.3, 0.1) which will cause all level 2
headers to display in red. If no element name is specified, the settings apply to the
SimpleHTML widget’s default font.
Like ScrollingMessageFrame, SimpleHTML also provides hyperlink support, includ-
ing a hook to control the formatting of hyperlinked text with :SetHyperlinkFormat.
This function takes a string, which is provided to string.format along with strings
representing the hyperlink’s address and body text, and produces the appropriate link
and color codes along with any other desired formatting.
This widget does not support scrolling by itself, but you can use it as a ScrollChild
to support longer blocks of text. In addition, it is used by the stock UI to display the
contents of the books that your character may find lying around inns and libraries.
SimpleHTML has all the methods from Frame, plus the following:
GetFont
Returns basic properties of a font used in the frame.
filename, fontHeight, flags = SimpleHTML:GetFont([“element“])
Arguments:
element (optional)Name of an HTML element for which to return font infor-
mation (e.g. p,h1); if omitted, returns information about the frame’s default font
(string)
Returns:
filename—Path to a font file (string)
fontHeightHeight (point size) of the font to be displayed (in pixels) (number)
flagsAdditional properties for the font specified by one or more (separated
by commas) of the following tokens: (string)
MONOCHROME - Font is rendered without anti-aliasing
OUTLINE - Font is displayed with a black outline
THICKOUTLINE - Font is displayed with a thick black outline
Chapter 29 Widget Reference 1209
GetFontObject
Returns the Font object from which the properties of a font used in the frame
are inherited.
font = SimpleHTML:GetFontObject([“element“])
Arguments:
element (optional)Name of an HTML element for which to return font infor-
mation (e.g. p,h1); if omitted, returns information about the frame’s default font
(string)
Returns:
fontReference to the Font object from which font properties are inherited, or
nil if no properties are inherited (font)
GetHyperlinkFormat
Returns the format string used for displaying hyperlinks in the frame.
format = SimpleHTML:GetHyperlinkFormat()
See :SetHyperlinkFormat() for details.
Returns:
formatFormat string used for displaying hyperlinks in the frame (string)
GetHyperlinksEnabled
Returns whether hyperlinks in the frame’s text are interactive.
enabled = SimpleHTML:GetHyperlinksEnabled()
Returns:
enabled1if hyperlinks in the frame’s text are interactive; otherwise nil
(1nil)
GetIndentedWordWrap
Returns whether long lines of text are indented when wrapping.
indent = SimpleHTML:GetIndentedWordWrap([“element“])
Arguments:
element (optional)Name of an HTML element for which to return text style
information (e.g. p,h1); if omitted, returns information about the frame’s default
text style (string)
Returns:
indent1if long lines of text are indented when wrapping; otherwise nil
(1nil)
GetJustifyH
Returns the horizontal alignment style for text in the frame.
justify = SimpleHTML:GetJustifyH([“element“])
Arguments:
element (optional)Name of an HTML element for which to return text style
information (e.g. p,h1); if omitted, returns information about the frame’s default
text style (string)
1210 Part IV Reference
Returns:
justifyHorizontal text alignment style (string,justifyH)
CENTER
LEFT
RIGHT
GetJustifyV
Returns the vertical alignment style for text in the frame.
justify = SimpleHTML:GetJustifyV([“element“])
Arguments:
element (optional)Name of an HTML element for which to return text style
information (e.g. p,h1); if omitted, returns information about the frame’s default
text style (string)
Returns:
justifyVertical text alignment style (string,justifyV)
BOTTOM
MIDDLE
TOP
GetShadowColor
Returns the shadow color for text in the frame.
shadowR, shadowG, shadowB, shadowAlpha = i
SimpleHTML:GetShadowColor([“element“])
Arguments:
element (optional)Name of an HTML element for which to return font infor-
mation (e.g. p,h1); if omitted, returns information about the frame’s default font
(string)
Returns:
shadowRRed component of the shadow color (0.0 - 1.0) (number)
shadowGGreen component of the shadow color (0.0 - 1.0) (number)
shadowBBlue component of the shadow color (0.0 - 1.0) (number)
shadowAlphaAlpha (opacity) of the text’s shadow (0.0 =fully
transparent, 1.0 =fully opaque) (number)
GetShadowOffset
Returns the offset of text shadow from text in the frame.
xOffset, yOffset = SimpleHTML:GetShadowOffset([“element“])
Arguments:
element (optional)Name of an HTML element for which to return font infor-
mation (e.g. p,h1); if omitted, returns information about the frame’s default font
(string)
Returns:
xOffsetHorizontal distance between the text and its shadow (in
pixels) (number)
Chapter 29 Widget Reference 1211
yOffsetVertical distance between the text and its shadow (in pixels)
(number)
GetSpacing
Returns the amount of spacing between lines of text in the frame.
spacing = SimpleHTML:GetSpacing([“element“])
Arguments:
element (optional)Name of an HTML element for which to return font infor-
mation (e.g. p,h1); if omitted, returns information about the frame’s default font
(string)
Returns:
spacingAmount of space between lines of text (in pixels)
(number)
GetTextColor
Returns the color of text in the frame.
textR, textG, textB, textAlpha = SimpleHTML:GetTextColor([“element“])
Arguments:
element (optional)Name of an HTML element for which to return font infor-
mation (e.g. p,h1); if omitted, returns information about the frame’s default font
(string)
Returns:
textRRed component of the text color (0.0 - 1.0) (number)
textGGreen component of the text color (0.0 - 1.0) (number)
textBBlue component of the text color (0.0 - 1.0) (number)
textAlphaAlpha(opacity)ofthetext(0.0=fully transparent, 1.0 =fully
opaque) (number)
SetFont
Sets basic properties of a font used in the frame.
isValid = SimpleHTML:SetFont([“element“,]i
“filename“, fontHeight, “flags“)
Arguments:
element (optional)Name of an HTML element for which to set font properties
(e.g. p,h1); if omitted, sets properties for the frame’s default font (string)
filename—Path to a font file (string)
fontHeightHeight (point size) of the font to be displayed (in pixels) (number)
flagsAdditional properties for the font specified by one or more (separated
by commas) of the following tokens: (string)
MONOCHROME - Font is rendered without anti-aliasing
OUTLINE - Font is displayed with a black outline
THICKOUTLINE - Font is displayed with a thick black outline
Returns:
isValid1if filename refers to a valid font file; otherwise nil (1nil)
1212 Part IV Reference
SetFontObject
Sets the Font object from which the properties of a font used in the frame are
inherited.
SimpleHTML:SetFontObject([“element“,] font) or i
SimpleHTML:SetFontObject([“element“,] “name“)
This method allows for easy standardization and reuse of font styles. For
example, a SimpleHTML frame’s normal font can be set to appear in the same
style as many default UI elements by setting its font to
“GameFontNormal“if Blizzard changes the main UI font in a future path, or
if the user installs another addon that changes the main UI font, the button’s
font will automatically change to match.
Arguments:
element (optional)Name of an HTML element for which to set font properties
(e.g. p,h1); if omitted, sets properties for the frame’s default font (string)
fontReference to a Font object (table)
name—Global name of a Font object (string)
SetHyperlinkFormat
Sets the format string used for displaying hyperlinks in the frame.
SimpleHTML:SetHyperlinkFormat(“format“)
Hyperlinks are specified via HTML in the text input to a SimpleHTML frame,
but in order to be handled as hyperlinks by the game’s
text engine they need to be formatted like the hyperlinks used elsewhere.
This property specifies the translation between formats: its default value of
|H%s|h%s|h provides minimal formatting, turning (for example) <a
href=“achievement:892“>The Right Stuff</a> into
|Hachievement:892|hThe Right Stuff|h.UsingacolorString or other
formatting may be useful for making hyperlinks distinguishable from other
text.
Arguments:
formatFormat string used for displaying hyperlinks in the frame (string)
SetHyperlinksEnabled
Enables or disables hyperlink interactivity in the frame.
SimpleHTML:SetHyperlinksEnabled(enable)
The frame’s hyperlink-related script handlers will only be run if hyperlinks are
enabled.
Arguments:
enableTrue to enable hyperlink interactivity in the frame; false to
disable (boolean)
SetIndentedWordWrap
Sets whether long lines of text are indented when wrapping.
SimpleHTML:SetIndentedWordWrap([“element“,] indent)
Chapter 29 Widget Reference 1213
Arguments:
element (optional)Name of an HTML element for which to set font properties
(e.g. p,h1); if omitted, sets properties for the frame’s default font (string)
indentTrue to indent wrapped lines of text; false otherwise (boolean)
SetJustifyH
Sets the horizontal alignment style for text in the frame.
SimpleHTML:SetJustifyH([“element“,] “justify“)
Arguments:
element (optional)Name of an HTML element for which to set properties
(e.g. p,h1); if omitted, sets properties of the frame’s default text style (string)
justifyHorizontal text alignment style (string,justifyH)
CENTER
LEFT
RIGHT
SetJustifyV
Sets the vertical alignment style for text in the frame.
SimpleHTML:SetJustifyV([“element“,] “justify“)
Arguments:
element (optional)Name of an HTML element for which to return text style
information (e.g. p,h1); if omitted, returns information about the frame’s default
text style (string)
justifyVertical text alignment style (string,justifyV)
BOTTOM
MIDDLE
TOP
SetShadowColor
Sets the shadow color for text in the frame.
SimpleHTML:SetShadowColor([“element“,] shadowR, shadowG, i
shadowB, shadowAlpha)
Arguments:
element (optional)Name of an HTML element for which to set font properties
(e.g. p,h1); if omitted, sets properties for the frame’s default font (string)
shadowRRed component of the shadow color (0.0 - 1.0) (number)
shadowGGreen component of the shadow color (0.0 - 1.0) (number)
shadowBBlue component of the shadow color (0.0 - 1.0) (number)
shadowAlphaAlpha (opacity) of the text’s shadow (0.0 =fully transparent, 1.0
=fully opaque) (number)
SetShadowOffset
Returns the offset of text shadow from text in the frame.
SimpleHTML:SetShadowOffset([“element“,] xOffset, yOffset)
1214 Part IV Reference
Arguments:
element (optional)Name of an HTML element for which to set font properties
(e.g. p,h1); if omitted, sets properties for the frame’s default font (string)
xOffsetHorizontal distance between the text and its shadow (in
pixels) (number)
yOffsetVertical distance between the text and its shadow (in pixels)
(number)
SetSpacing
Sets the amount of spacing between lines of text in the frame.
SimpleHTML:SetSpacing([“element“,] spacing)
Arguments:
element (optional)Name of an HTML element for which to set font properties
(e.g. p,h1); if omitted, sets properties for the frame’s default font (string)
spacingAmount of space between lines of text (in pixels) (number)
SetText
Sets the text to be displayed in the SimpleHTML frame.
SimpleHTML:SetText(“text“)
Text for display in the frame can be formatted using a simplified version of
HTML markup:
For HTML formatting, the entire text must be enclosed in <html><body>
and </body></html> tags.
All tags must be closed (img and br must use self-closing syntax; e.g. <br/>,
not <br>).
Tags are case insensitive, but closing tags must match the case of opening
tags.
Attribute values must be enclosed in single or double quotation marks (or
‘).
Characters occurring in HTML markup must be entity-escaped
(&quot; &lt; &gt; &amp;); no other entity-escapes are supported.
Unrecognized tags and their contents are ignored (e.g. given
<h1><foo>bar</foo>baz</h1>, only ‘‘baz’’ will appear).
Any HTML parsing error will result in the raw HTML markup being dis-
played.
Only the following tags and attributes are supported:
p,h1,h2,h3 - Block elements; e.g. <p align=“left“>
align - Text alignment style (optional); allowed values are left,center
and right.
img - Image; may only be used as a block element (not inline with
text); e.g. <img src=“Interface\Icons\INV_Misc_Rune_01“ />.
Chapter 29 Widget Reference 1215
src - Path to the image file (filename extension omitted).
align - Alignment of the image block in the frame (optional); allowed
values are left,center and right.
width - Width at which to display the image (in pixels; optional).
height - Height at which to display the image (in pixels; optional).
a- Inline hyperlink; e.g. <a href=“aLink“>text</a>
href - String identifying the link; passed as argument to
hyperlink-related scripts when the player interacts with the link.
br - Explicit line break in text; e.g. <br />.
Inline escape sequences used in FontStrings (e.g. colorStrings) may also be
used.
Arguments:
textText (with HTML markup) to be displayed (string)
SetTextColor
Sets the color of text in the frame.
SimpleHTML:SetTextColor([“element“,] textR, textG, textB, textAlpha)
Arguments:
element (optional)Name of an HTML element for which to set font properties
(e.g. p,h1); if omitted, sets properties for the frame’s default font (string)
textRRed component of the text color (0.0 - 1.0) (number)
textGGreen component of the text color (0.0 - 1.0) (number)
textBBlue component of the text color (0.0 - 1.0) (number)
textAlphaAlpha(opacity)ofthetext(0.0=fully transparent, 1.0 =fully
opaque) (number)
Slider
Sliders are elements intended to display or allow the user to choose a value in a range.
They are often used for configuration, to choose scale, camera distance and similar
settings.
Like Buttons, Sliders can be enabled or disabled, but unlike Buttons, they include
no support for automatically changing appearance when this is done. You can set both
their minimum and maximum values (one function returns or accepts both), and the
step by which dragging changes their value. Sliders can be oriented either horizontally
or vertically.
While you do not have to provide any code to manage the dragging of a slider’s
‘‘thumb’’, you do have to provide a texture that will represent it, which the engine will
position and draw automatically. In XML, you do this by providing a <ThumbTexture>
element as a direct child of the <Slider> element, which can have any of the attributes
or children allowed to any <Texture> element.
Sliders come in two common forms: thin tracks with a wide thumb, used for setting
scalar options, or scroll bars used for positioning the contents of a frame.
Slider has all the methods from Frame, plus the following:
1216 Part IV Reference
Disable
Disallows user interaction with the slider.
Slider:Disable()
Does not automatically change the visual state of the slider; directly making a
visible change is recommended in order to communicate the change in state to
the user.
Enable
Allows user interaction with the slider.
Slider:Enable()
GetMinMaxValues
Returns the minimum and maximum values for the slider.
minValue, maxValue = Slider:GetMinMaxValues()
Returns:
minValueLower boundary for values represented by the slider position
(number)
maxValueUpper boundary for values represented by the slider position
(number)
GetOrientation
Returns the orientation of the slider.
orientation = Slider:GetOrientation()
Returns:
orientationToken describing the orientation and direction of the slider
(string)
HORIZONTAL - Slider thumb moves from left to right as the slider’s value
increases
VERTICAL - Slider thumb moves from top to bottom as the slider’s value
increases
GetThumbTexture
Returns the texture for the slider thumb.
texture = Slider:GetThumbTexture()
Returns:
textureReference to the Texture object used for the slider thumb (texture)
GetValue
Returns the value representing the current position of the slider thumb.
value = Slider:GetValue()
Returns:
valueValue representing the current position of the slider thumb
(between minValue and maxValue,whereminValue, maxValue =
slider:GetMinMaxValues())(number)
Chapter 29 Widget Reference 1217
GetValueStep
Returns the minimum increment between allowed slider values.
step = Slider:GetValueStep()
Returns:
stepMinimum increment between allowed slider values (number)
IsEnabled
Returns whether user interaction with the slider is allowed.
enabled = Slider:IsEnabled()
Returns:
enabled1if user interaction with the slider is allowed; otherwise nil (1nil)
SetMinMaxValues
Sets the minimum and maximum values for the slider.
Slider:SetMinMaxValues(minValue, maxValue)
Arguments:
minValueLower boundary for values represented by the slider position
(number)
maxValueUpper boundary for values represented by the slider position
(number)
SetOrientation
Sets the orientation of the slider.
Slider:SetOrientation(“orientation“)
Arguments:
orientationToken describing the orientation and direction of the slider
(string)
HORIZONTAL - Slider thumb moves from left to right as the slider’s value
increases
VERTICAL - Slider thumb moves from top to bottom as the slider’s value
increases (default)
SetThumbTexture
Sets the texture for the slider thumb.
Slider:SetThumbTexture(texture [, “layer“]) or i
Slider:SetThumbTexture(“filename“ [, “layer“])
Arguments:
textureReference to an existing Texture object (texture)
filenamePath to a texture image file (string)
layer (optional)Graphics layer in which the texture should be
drawn; defaults to ARTWORK if not specified (string,layer)
SetValue
Sets the value representing the position of the slider thumb.
Slider:SetValue(value)
1218 Part IV Reference
Arguments:
valueValue representing the new position of the slider thumb
(between minValue and maxValue,whereminValue, maxValue =
slider:GetMinMaxValues())(number)
SetValueStep
Sets the minimum increment between allowed slider values.
Slider:SetValueStep(step)
The portion of the slider frame’s area in which the slider thumb moves is its
width (or height, for vertical sliders) minus 16 pixels on either end. If the
number of possible values determined by the slider’s minimum, maximum and
step values is less than the width (or height) of this area, the step value also
affects the movement of the slider thumb; see example for details.
Arguments:
stepMinimum increment between allowed slider values (number)
Example:
-- creates a sample horizontal slider
-- (also gives it the default UI’s standard slider background,
-- since sliders don’t automatically come with one)
CreateFrame(“Slider“,“S“,UIParent)
S:SetPoint(“CENTER“)
S:SetWidth(132)
S:SetHeight(17)
S:SetOrientation(“HORIZONTAL“)
S:SetThumbTexture(“Interface\\Buttons\\UI-SliderBar-Button-
Horizontal“)
S:SetMinMaxValues(0,100)
S:SetValue(50)
S:SetBackdrop({
bgFile = “Interface\\Buttons\\UI-SliderBar-Background“,
edgeFile = “Interface\\Buttons\\UI-SliderBar-Border“,
tile = true, tileSize = 8, edgeSize = 8,
insets = { left = 3, right = 3, top = 6, bottom = 6 }})
-- notice the slider thumb moves smoothly across the slider’s
-- length when dragged and S:GetValue() often returns non-integer
-- results when dragging
-- now, restrict the slider’s value step a bit:
S:SetValueStep(1)
-- notice the slider thumb still moves smoothly when dragged
-- but S:GetValue() now returns only integer results
-- further restricting the slider’s value step:
S:SetValueStep(25)
-- now the slider thumb can only be dragged to one of
-- five different positions: 0, 25, 50, 75, or 100
Chapter 29 Widget Reference 1219
StatusBar
StatusBars are similar to Sliders, but they are generally used for display as they don’t
offer any tools to receive user input. You define them with a bar texture and an
optional color, and they fill a portion of their area in a given direction with that texture
according to their value.
StatusBars can be oriented to fill from left to right (HORIZONTAL) or from bottom
to top (VERTICAL). If you need to share the same bar texture between horizontal
and vertical bars, they offer support for rotating the texture automatically to match.
Presently, the StatusBar object does not support right-to-left or top-to-bottom bars.
StatusBars also offer an OnValueChanged handler to update information associated
with the bar, such as updating a FontString that displays the bar’s value as a number.
The most famous StatusBars in the stock UI are the bars that show your health and
mana, and those of your group members and target.
StatusBar has all the methods from Frame, plus the following:
GetMinMaxValues
Returns the minimum and maximum values of the status bar.
minValue, maxValue = StatusBar:GetMinMaxValues()
Returns:
minValueLower boundary for values represented on the status bar (number)
maxValueUpper boundary for values represented on the status bar (number)
GetOrientation
Returns the orientation of the status bar.
orientation = StatusBar:GetOrientation()
Returns:
orientationToken describing the orientation and direction of the
status bar (string)
HORIZONTAL - Fills from left to right as the status bar value increases
VERTICAL - Fills from top to bottom as the status bar value increases
GetRotatesTexture
Returns whether the status bar’s texture is rotated to match its orientation.
rotate = StatusBar:GetRotatesTexture()
Returns:
rotate1if the status bar texture should be rotated 90 degrees
counter-clockwise when the status bar is vertically oriented; otherwise nil
(1nil)
GetStatusBarColor
Returns the color shading used for the status bar’s texture.
red, green, blue, alpha = StatusBar:GetStatusBarColor()
Returns:
redRed component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
1220 Part IV Reference
blueBlue component of the color (0.0 - 1.0) (number)
alpha (optional)Alpha (opacity) for the graphic (0.0 =fully transparent, 1.0 =
fully opaque) (number)
GetStatusBarTexture
Returns the Texture object used for drawing the filled-in portion of the status
bar.
texture = StatusBar:GetStatusBarTexture()
Returns:
textureReference to the Texture object used for drawing the filled-in por-
tion of the status bar (texture)
GetValue
Returns the current value of the status bar.
value = StatusBar:GetValue()
Returns:
valueValue indicating the amount of the status bar’s area to
be filled in (between minValue and maxValue,whereminValue,
maxValue = StatusBar:GetMinMaxValues())(number)
SetMinMaxValues
Sets the minimum and maximum values of the status bar.
StatusBar:SetMinMaxValues(minValue, maxValue)
Arguments:
minValueLower boundary for values represented on the status bar (number)
maxValueUpper boundary for values represented on the status bar (number)
SetOrientation
Sets the orientation of the status bar.
StatusBar:SetOrientation(“orientation“)
Arguments:
orientationToken describing the orientation and direction of the status bar
(string)
HORIZONTAL - Fills from left to right as the status bar value increases (default)
VERTICAL - Fills from top to bottom as the status bar value increases
SetRotatesTexture
Sets whether the status bar’s texture is rotated to match its orientation.
StatusBar:SetRotatesTexture(rotate)
Arguments:
rotateTrue to rotate the status bar texture 90 degrees counter-
clockwise when the status bar is vertically oriented; false otherwise (1nil)
SetStatusBarColor
Sets the color shading for the status bar’s texture.
StatusBar:SetStatusBarColor(red, green, blue [, alpha])
Chapter 29 Widget Reference 1221
As with :SetVertexColor(), this color is a shading applied to the texture
image.
Arguments:
redRed component of the color (0.0 - 1.0) (number)
greenGreen component of the color (0.0 - 1.0) (number)
blueBlue component of the color (0.0 - 1.0) (number)
alpha (optional)Alpha (opacity) for the graphic (0.0 =fully transparent, 1.0 =
fully opaque) (number)
SetStatusBarTexture
Sets the texture used for drawing the filled-in portion of the status bar.
StatusBar:SetStatusBarTexture(texture [, “layer“]) or i
StatusBar:SetStatusBarTexture(“filename“ [, “layer“])
The texture image is stretched to fill the dimensions of the entire status bar,
then cropped to show only a portion corresponding to the status bar’s current
value.
Arguments:
textureReference to an existing Texture object (texture)
filenamePath to a texture image file (string)
layer (optional)Graphics layer in which the texture should be
drawn; defaults to ARTWORK if not specified (string,layer)
SetValue
Sets the value of the status bar.
StatusBar:SetValue(value)
Arguments:
valueValue indicating the amount of the status bar’s area to
be filled in (between minValue and maxValue,whereminValue,
maxValue = StatusBar:GetMinMaxValues())(number)
Font
The Font object is the only type of object that is not attached to a parent widget; indeed,
its purpose is to be shared between other objects that share font characteristics. In this
way, changes to the Font object will update the text appearance of all text objects that
have it set as their Font using :SetFontObject(). This allows a coder to maintain a
consistent appearance between UI elements, as well as simplifying the resources and
work required to update multiple text-based UI elements.
Font has all the methods from UIObject and FontInstance, plus the
following:
CopyFontObject
Sets the font’s properties to match those of another Font object.
Font:CopyFontObject(object) or Font:CopyFontObject(“name“)
1222 Part IV Reference
Unlike FontInstance:SetFontObject(), this method allows one-time reuse
of another font object’s properties without continuing to inherit future changes
made to the other object’s properties.
Arguments:
objectReference to a Font object (font)
name—Global name of a Font object (string)
GetAlpha
Returns the opacity for text displayed by the font.
alpha = Font:GetAlpha()
Returns:
alphaAlpha(opacity)ofthetext(0.0=fully transparent, 1.0 =fully opaque)
(number)
GetMultilineIndent
Returns whether long lines of text are indented when wrapping.
indent = Font:GetMultilineIndent()
Returns:
indent1if long lines of text are indented when wrapping; otherwise nil
(1nil)
SetAlpha
Sets the opacity for text displayed by the font.
Font:SetAlpha(alpha)
Arguments:
alphaAlpha(opacity)ofthetext(0.0=fully transparent, 1.0 =fully opaque)
(number)
SetMultilineIndent
Sets whether long lines of text are indented when wrapping.
Font:SetMultilineIndent(indent)
Arguments:
indentTrue to indent wrapped lines of text; false otherwise
(boolean)
MessageFrame
MessageFrames are used to present series of messages or other lines of text, usually
stacked on top of each other. Like most widgets relating to text display, MessageFrame
inherits from FontInstance as well as Frame to provide methods for setting up text
characteristics. Once the text settings for the frame are configured to your liking,
you can add new messages to the frame with :AddMessage(). MessageFrame also
supports methods for multi-line text display such as indented lines, as well as options
for controlling how long messages should be displayed and how quickly they fade out
when their time is up.
Chapter 29 Widget Reference 1223
The stock UI uses the basic message frame for only one purpose, but it gets a lot
of use; UIErrorsFrame, which displays messages like ‘‘Spell not ready yet’’ or ‘‘You’re
too far away’’, is a MessageFrame. MessageFrame also forms the basis for another,
more sophisticated type, ScrollingMessageFrame.
MessageFrame has all the methods from Frame and FontInstance, plus the following:
AddMessage
Adds a message to those listed in the frame.
MessageFrame:AddMessage(“text“ [, red [, green [, blue [, alpha]]]])
If the frame was already ‘full’ with messages, then the oldest message is
discarded when the new one is added.
Arguments:
textText of the message (string)
red (optional)Red component of the text color for the message (0.0 - 1.0)
(number)
green (optional)Green component of the text color for the message
(0.0 - 1.0) (number)
blue (optional)Blue component of the text color for the message (0.0 - 1.0)
(number)
alpha (optional)Alpha (opacity) for the message (0.0 =fully transparent, 1.0
=fully opaque) (number)
Clear
Removes all messages displayed in the frame.
MessageFrame:Clear()
GetFadeDuration
Returns the duration of the fade-out animation for disappearing messages.
duration = MessageFrame:GetFadeDuration()
For the amount of time a message remains in the frame before beginning to
fade, see :GetTimeVisible().
Returns:
durationDuration of the fade-out animation for disappearing messages (in
seconds) (number)
GetFading
Returns whether messages added to the frame automatically fade out after a
period of time.
fading = MessageFrame:GetFading()
Returns:
fading1if messages added to the frame automatically fade out after a period
of time; otherwise nil (1nil)
GetIndentedWordWrap
Returns whether long lines of text are indented when wrapping.
indent = MessageFrame:GetIndentedWordWrap()
1224 Part IV Reference
Returns:
indent1if long lines of text are indented when wrapping; otherwise nil
(1nil)
GetInsertMode
Returns the position at which new messages are added to the frame.
position = MessageFrame:GetInsertMode()
Returns:
positionToken identifying the position at which new messages are added to
the frame (string)
BOTTOM
TOP
GetTimeVisible
Returns the amount of time for which a message remains visible before
beginning to fade out.
time = MessageFrame:GetTimeVisible()
For the duration of the fade-out animation, see :GetFadeDuration().
Returns:
timeAmount of time for which a message remains visible before beginning to
fade out (in seconds) (number)
SetFadeDuration
Sets the duration of the fade-out animation for disappearing messages.
MessageFrame:SetFadeDuration(duration)
For the amount of time a message remains in the frame before beginning to
fade, see :SetTimeVisible().
Arguments:
durationDuration of the fade-out animation for disappearing messages (in
seconds) (number)
SetFading
Sets whether messages added to the frame automatically fade out after a
period of time.
MessageFrame:SetFading(fading)
Arguments:
fadingTrue to cause messages added to the frame to automati-
cally fade out after a period of time; false to leave message visible
(boolean)
SetIndentedWordWrap
Sets whether long lines of text are indented when wrapping.
MessageFrame:SetIndentedWordWrap(indent)
Arguments:
indentTrue to indent wrapped lines of text; false otherwise
(boolean)
Chapter 29 Widget Reference 1225
SetInsertMode
Sets the position at which new messages are added to the frame.
MessageFrame:SetInsertMode(“position“)
Arguments:
positionToken identifying the position at which new messages should be
added to the frame (string)
BOTTOM
TOP
SetTimeVisible
Sets the amount of time for which a message remains visible before beginning
to fade out.
MessageFrame:SetTimeVisible(time)
For the duration of the fade-out animation, see :SetFadeDuration().
Arguments:
timeAmount of time for which a message remains visible before beginning to
fade out (in seconds) (number)
ScrollingMessageFrame
ScrollingMessageFrame expands on MessageFrame with the ability to store a much
longer series of messages, and to move up and down through them by setting horizontal
and vertical scroll values, or by using PageUp and PageDown methods.
ScrollingMessageFrames also support hyperlinkssuch as the links posted in trade
chat by people with items they want to selland provides an OnHyperlinkClicked
script for displaying information related to the contents of the link.
The most common ScrollingMessageFrame in the stock UI is simply the chat frame,
as well as the combat log. The raid warning and boss emote messages are presented in
a ScrollingMessageFrame. The Guild Bank UI also uses one to display the transaction
history.
ScrollingMessageFrame has all the methods from Frame and FontInstance, plus the
following:
AddMessage
Adds a message to those listed in the frame.
ScrollingMessageFrame:AddMessage(“text“ [, red [, green i
[, blue [, id [, addToTop]]]]])
Arguments:
textText of the message (string)
red (optional)Red component of the text color for the message (0.0 - 1.0)
(number)
green (optional)Green component of the text color for the message
(0.0 - 1.0) (number)
blue (optional)Blue component of the text color for the message (0.0 - 1.0)
(number)
1226 Part IV Reference
id (optional)Identifier for the message’s type (see :UpdateColor-
ByID())(number)
addToTop (optional)True to insert the message above all others
listed in the frame, even if the frame’s insert mode is set to BOTTOM;
false to insert according to the frame’s insert mode (boolean)
AtBottom
Returns whether the message frame is currently scrolled to the bottom of its
contents.
atBottom = ScrollingMessageFrame:AtBottom()
Returns:
atBottom1if the message frame is currently scrolled to the bottom of its con-
tents; otherwise nil (1nil)
AtTop
Returns whether the message frame is currently scrolled to the top of its
contents.
atTop = ScrollingMessageFrame:AtTop()
Returns:
atTop1if the message frame is currently scrolled to the top of its
contents; otherwise nil (1nil)
Clear
Removes all messages stored or displayed in the frame.
ScrollingMessageFrame:Clear()
GetCurrentLine
Returns a number identifying the last message added to the frame.
lineNum = ScrollingMessageFrame:GetCurrentLine()
This number starts at 0when the frame is created and increments with each
message AddMessage to the frame; however, it resets to 0when a message is
added beyond the frame’s GetMaxLines.
Returns:
lineNumA number identifying the last message added to the frame (number)
GetCurrentScroll
Returns the message frame’s current scroll position.
offset = ScrollingMessageFrame:GetCurrentScroll()
Returns:
offsetNumber of lines by which the frame is currently scrolled back from the
end of its message history (number)
GetFadeDuration
Returns the duration of the fade-out animation for disappearing messages.
duration = ScrollingMessageFrame:GetFadeDuration()
Chapter 29 Widget Reference 1227
For the amount of time a message remains in the frame before beginning to
fade, see :GetTimeVisible().
Returns:
durationDuration of the fade-out animation for disappearing messages (in
seconds) (number)
GetFading
Returns whether messages added to the frame automatically fade out after a
period of time.
fading = ScrollingMessageFrame:GetFading()
Returns:
fading1if messages added to the frame automatically fade out after a period
of time; otherwise nil (1nil)
GetHyperlinksEnabled
Returns whether hyperlinks in the frame’s text are interactive.
enabled = ScrollingMessageFrame:GetHyperlinksEnabled()
Returns:
enabled1if hyperlinks in the frame’s text are interactive; otherwise nil
(1nil)
GetIndentedWordWrap
Returns whether long lines of text are indented when wrapping.
indent = ScrollingMessageFrame:GetIndentedWordWrap()
Returns:
indent1if long lines of text are indented when wrapping; otherwise nil
(1nil)
GetInsertMode
Returns the position at which new messages are added to the frame.
position = ScrollingMessageFrame:GetInsertMode()
Returns:
positionToken identifying the position at which new messages are added to
the frame (string)
BOTTOM
TOP
GetMaxLines
Returns the maximum number of messages kept in the frame.
ScrollingMessageFrame:GetMaxLines(maxLines)
Arguments:
maxLinesMaximum number of messages kept in the frame (number)
GetNumLinesDisplayed
Returns the number of lines displayed in the message frame.
count = ScrollingMessageFrame:GetNumLinesDisplayed()
1228 Part IV Reference
This number reflects the list of messages currently displayed, not including
those which are stored for display if the frame is scrolled.
Returns:
countNumber of messages currently displayed in the frame (number)
GetNumMessages
Returns the number of messages currently kept in the frame’s message history.
count = ScrollingMessageFrame:GetNumMessages()
This number reflects the list of messages which can be seen by scrolling the
frame, including (but not limited to) the list of messages currently
displayed.
Returns:
countNumber of messages currently kept in the frame’s message history
(number)
GetTimeVisible
Returns the amount of time for which a message remains visible before
beginning to fade out.
time = ScrollingMessageFrame:GetTimeVisible()
Returns:
timeAmount of time for which a message remains visible before beginning to
fade out (in seconds) (number)
PageDown
Scrolls the message frame’s contents down by one page.
ScrollingMessageFrame:PageDown()
One ‘‘page’’ is slightly less than the number of lines displayed in the frame.
PageUp
Scrolls the message frame’s contents up by one page.
ScrollingMessageFrame:PageUp()
One ‘‘page’’ is slightly less than the number of lines displayed in the frame.
ScrollDown
Scrolls the message frame’s contents down by two lines.
ScrollingMessageFrame:ScrollDown()
ScrollToBottom
Scrolls to the bottom of the message frame’s contents.
ScrollingMessageFrame:ScrollToBottom()
ScrollToTop
Scrolls to the top of the message frame’s contents.
ScrollingMessageFrame:ScrollToTop()
Chapter 29 Widget Reference 1229
ScrollUp
Scrolls the message frame’s contents up by two lines.
ScrollingMessageFrame:ScrollUp()
SetFadeDuration
Sets the duration of the fade-out animation for disappearing messages.
ScrollingMessageFrame:SetFadeDuration(duration)
For the amount of time a message remains in the frame before beginning to
fade, see :SetTimeVisible().
Arguments:
durationDuration of the fade-out animation for disappearing messages (in
seconds) (number)
SetFading
Sets whether messages added to the frame automatically fade out after a
period of time.
ScrollingMessageFrame:SetFading(fading)
Arguments:
fadingTrue to cause messages added to the frame to automati-
cally fade out after a period of time; false to leave message visible
(boolean)
SetHyperlinksEnabled
Enables or disables hyperlink interactivity in the frame.
ScrollingMessageFrame:SetHyperlinksEnabled(enable)
The frame’s hyperlink-related script handlers will only be run if hyperlinks are
enabled.
Arguments:
enableTrue to enable hyperlink interactivity in the frame; false to disable
(boolean)
SetIndentedWordWrap
Sets whether long lines of text are indented when wrapping.
ScrollingMessageFrame:SetIndentedWordWrap(indent)
Arguments:
indentTrue to indent wrapped lines of text; false otherwise
(boolean)
SetInsertMode
Sets the position at which new messages are added to the frame.
ScrollingMessageFrame:SetInsertMode(“position“)
Arguments:
positionToken identifying the position at which new messages should be
added to the frame (string)
1230 Part IV Reference
BOTTOM
TOP
SetMaxLines
Sets the maximum number of messages to be kept in the frame.
ScrollingMessageFrame:SetMaxLines(maxLines)
If additional messages are added beyond this number, the oldest lines are
discarded and can no longer be seen by scrolling.
Arguments:
maxLinesMaximum number of messages to be kept in the frame (number)
SetScrollOffset
Sets the message frame’s scroll position.
ScrollingMessageFrame:SetScrollOffset(offset)
Arguments:
offsetNumber of lines to scroll back from the end of the frame’s message his-
tory (number)
SetTimeVisible
Sets the amount of time for which a message remains visible before beginning
to fade out.
ScrollingMessageFrame:SetTimeVisible(time)
For the duration of the fade-out animation, see :SetFadeDuration().
Arguments:
timeAmount of time for which a message remains visible before beginning to
fade out (in seconds) (number)
UpdateColorByID
Updates the color of a set of messages already added to the frame.
ScrollingMessageFrame:UpdateColorByID(id, red, green, blue)
Used in the default UI to allow customization of chat window message colors
by type: each type of chat window message (party, raid, emote, system
message, etc) has a numeric identifier found in the global table ChatTypeInfo;
this is passed as the fifth argument to :AddMessage() when messages are
added to the frame, allowing them to be identified for recoloring via this
method.
Arguments:
idIdentifier for a message’s type (as set when the messages were added to the
frame) (number)
redRed component of the new text color (0.0 - 1.0) (number)
greenGreen component of the new text color (0.0 - 1.0) (number)
blueBlue component of the new text color (0.0 - 1.0) (number)
Chapter 29 Widget Reference 1231
EditBox
EditBoxes are used to allow the player to type text into a UI component. They inherit
from FontInstance as well as Frame in order to provide the needed support for
text display, and add methods for entering text, such as positioning a cursor within
text, establishing character limits, controlling whether text should be displayed in
password-fashion (with bullets substituted for the characters), manipulating an entry
history, or controlling and responding to changes in keyboard focus.
The most common use for an EditBox is to accept chat input from the player, but they
are also used for commands, configuration and confirmation, such as requiring you to
type ‘‘DELETE’’ before destroying a valuable item, or entering the name of a new macro.
Most EditBoxes are derived from ChatFrameEditBoxTemplate, or use the same
textures to create a visible frame around the editable area.
EditBox has all the methods from Frame and FontInstance, plus the
following:
AddHistoryLine
Adds a line of text to the edit box’s stored history.
EditBox:AddHistoryLine(“text“)
Once added, the user can quickly set the edit box’s contents to one of these
lines by pressing the up or down arrow keys. (History lines are only accessible
via the arrow keys if the edit box is not in multi-line mode.)
Arguments:
textText to be added to the edit box’s list of history lines (string)
ClearFocus
Releases keyboard input focus from the edit box.
EditBox:ClearFocus()
GetAltArrowKeyMode
Returns whether arrow keys are ignored by the edit box unless the Alt key is
held.
enabled = EditBox:GetAltArrowKeyMode()
Returns:
enabled1if arrow keys are ignored by the edit box unless the Alt key is held;
otherwise nil (1nil)
GetBlinkSpeed
Returns the rate at which the text insertion blinks when the edit box is focused.
duration = EditBox:GetBlinkSpeed()
Returns:
durationAmount of time for which the cursor is visible during each ‘‘blink’’
(in seconds) (number)
GetCursorPosition
Returns the current cursor position inside edit box.
position = EditBox:GetCursorPosition()
1232 Part IV Reference
Returns:
positionCurrent position of the keyboard input cursor (between 0, for the
position before the first character, and editbox:GetNumLetters(),forthe
position after the last character) (number)
GetHistoryLines
Returns the maximum number of history lines stored by the edit box.
count = EditBox:GetHistoryLines()
Returns:
countMaximum number of history lines stored by the edit box (number)
GetIndentedWordWrap
Returns whether long lines of text are indented when wrapping.
indent = EditBox:GetIndentedWordWrap()
Returns:
indent1if long lines of text are indented when wrapping; otherwise nil
(1nil)
GetInputLanguage
Returns the currently selected keyboard input language (character set / input
method).
language = EditBox:GetInputLanguage()
Applies to keyboard input methods, not in-game languages or client locales.
Returns:
languageToken representing the current keyboard input method (string)
GetMaxBytes
Returns the maximum number of bytes of text allowed in the edit box.
maxBytes = EditBox:GetMaxBytes()
Note: Unicode characters may consist of more than one byte each, so the
behavior of a byte limit may differ from that of a character limit in practical
use.
Returns:
maxBytesMaximum number of text bytes allowed in the edit box (number)
GetMaxLetters
Returns the maximum number of text characters allowed in the edit box.
maxLetters = EditBox:GetMaxLetters()
Returns:
maxLettersMaximum number of text characters allowed in the edit box
(number)
GetNumLetters
Returns the number of text characters in the edit box.
numLetters = EditBox:GetNumLetters()
Chapter 29 Widget Reference 1233
Returns:
numLettersNumber of text characters in the edit box (number)
GetNumber
Returns the contents of the edit box as a number.
num = EditBox:GetNumber()
Similar to tonumber(editbox:GetText());returns0if the contents of the
edit box cannot be converted to a number.
Returns:
numContents of the edit box as a number (number)
GetText
Returnstheeditboxstextcontents.
text = EditBox:GetText()
Returns:
textText contained in the edit box (string)
GetTextInsets
Returns the insets from the edit box’s edges which determine its interactive
text area.
left, right, top, bottom = EditBox:GetTextInsets()
Returns:
leftDistance from the left edge of the edit box to the left edge of its interac-
tive text area (in pixels) (number)
rightDistance from the right edge of the edit box to the right edge of its inter-
active text area (in pixels) (number)
topDistance from the top edge of the edit box to the top edge of its interactive
text area (in pixels) (number)
bottomDistance from the bottom edge of the edit box to the
bottom edge of its interactive text area (in pixels) (number)
GetUTF8CursorPosition
Returns the cursor’s numeric position in the edit box, taking UTF-8 multi-byte
character into account.
position = EditBox:GetUTF8CursorPosition()
If the EditBox contains multi-byte Unicode characters, the
GetCursorPosition() method will not return correct results, as it considers
each eight byte character to count as a single glyph. This method properly
returns the position in the edit box from the perspective of the user.
Returns:
positionThe cursor’s numeric position (leftmost position is
0), taking UTF8 multi-byte characters into account. (number)
HasFocus
Returns whether the edit box is currently focused for keyboard input.
enabled = EditBox:HasFocus()
1234 Part IV Reference
Returns:
enabled1if the edit box is currently focused for keyboard input; otherwise
nil (1nil)
HighlightText
Selects all or a portion of the text in the edit box.
EditBox:HighlightText([start [, end]])
Arguments:
start (optional)Character position at which to begin the selection (between
0, for the position before the first character, and editbox:GetNumLetters(),
for the position after the last character); defaults to 0 if not specified (number)
end (optional)Character position at which to end the selection; if not specified
or if less than start, selects all characters after the start position; if equal to
start, selects nothing and positions the cursor at the start position (number)
Insert
Inserts text into the edit box at the current cursor position.
EditBox:Insert(“text“)
Arguments:
textText to be inserted (string)
IsAutoFocus
Returns whether the edit box automatically acquires keyboard input focus.
enabled = EditBox:IsAutoFocus()
Returns:
enabled1if the edit box automatically acquires keyboard input focus; other-
wise nil (1nil)
IsInIMECompositionMode
Returns whether the edit box is in Input Method Editor composition mode.
enabled = EditBox:IsInIMECompositionMode()
Character composition mode is used for input methods in which multiple
keypresses generate one printed character. In such input methods, the edit
box’s OnChar script is run for each keypressif the OnChar script should act
only when a complete character is entered in the edit box,
:IsInIMECompositionMode() can be used to test for such cases.
This mode is common in clients for languages using non-Roman characters
(such as Chinese or Korean), but can still occur in client languages using
Roman scripts (e.g. English)such as when typing accented characters on the
Mac client (e.g. typing ‘‘option-u’’ then ‘‘e’’ to insert the character ‘‘¨
e’’).
Returns:
enabled1if the edit box is in IME character composition mode; otherwise nil
(1nil)
IsMultiLine
Returns whether the edit box shows more than one line of text.
multiLine = EditBox:IsMultiLine()
Chapter 29 Widget Reference 1235
Returns:
multiLine1if the edit box shows more than one line of text; otherwise nil
(1nil)
IsNumeric
Returns whether the edit box only accepts numeric input.
enabled = EditBox:IsNumeric()
Returns:
enabled1if only numeric input is allowed; otherwise nil (1nil)
IsPassword
Returns whether the text entered in the edit box is masked.
enabled = EditBox:IsPassword()
Returns:
enabled1if text entered in the edit box is masked with asterisk characters (*);
otherwise nil (1nil)
SetAltArrowKeyMode
Sets whether arrow keys are ignored by the edit box unless the Alt key is held.
EditBox:SetAltArrowKeyMode(enable)
Arguments:
enableTrue to cause the edit box to ignore arrow key presses unless the Alt
key is held; false to allow unmodified arrow key presses for cursor movement
(boolean)
SetAutoFocus
Sets whether the edit box automatically acquires keyboard input focus.
EditBox:SetAutoFocus(enable)
If auto-focus behavior is enabled, the edit box automatically acquires keyboard
focus when it is shown and when no other edit box is focused.
Arguments:
enableTrue to enable the edit box to automatically acquire keyboard input
focus; false to disable (boolean)
SetBlinkSpeed
Sets the rate at which the text insertion blinks when the edit box is focused.
EditBox:SetBlinkSpeed(duration)
The speed indicates how long the cursor stays in each state (shown and
hidden); e.g. if the blink speed is 0.5 (the default, the cursor is shown for one
half second and then hidden for one half second (thus, a one-second cycle); if
the speed is 1.0, the cursor is shown for one second and then hidden for one
second (a two-second cycle).
Arguments:
durationAmount of time for which the cursor is visible during each ‘‘blink’’
(in seconds) (number)
1236 Part IV Reference
SetCursorPosition
Sets the cursor position in the edit box.
EditBox:SetCursorPosition(position)
Arguments:
positionNew position for the keyboard input cursor (between 0, for the
position before the first character, and editbox:GetNumLetters(),forthe
position after the last character) (number)
SetFocus
Focuses the edit box for keyboard input.
EditBox:SetFocus()
Only one edit box may be focused at a time; setting focus to one edit box will
remove it from the currently focused edit box.
SetHistoryLines
Sets the maximum number of history lines stored by the edit box.
EditBox:SetHistoryLines(count)
Lines of text can be added to the edit box’s history by calling
:AddHistoryLine(); once added, the user can quickly set the edit box’s
contents to one of these lines by pressing the up or down arrow keys. (History
lines are only accessible via the arrow keys if the edit box is not in multi-line
mode.)
Arguments:
countMaximum number of history lines to be stored by the edit box (number)
SetIndentedWordWrap
Sets whether long lines of text are indented when wrapping.
EditBox:SetIndentedWordWrap(indent)
Arguments:
indentTrue to indent wrapped lines of text; false otherwise
(boolean)
SetMaxBytes
Sets the maximum number of bytes of text allowed in the edit box.
EditBox:SetMaxBytes(maxBytes)
Attempts to type more than this number into the edit box will produce no
results; programmatically inserting text or setting the edit box’s text will
truncate input to the maximum length.
Note: Unicode characters may consist of more than one byte each, so the beha-
vior of a byte limit may differ from that of a character limit in practical use.
Arguments:
maxBytesMaximum number of text bytes allowed in the edit box, or 0for no
limit (number)
Chapter 29 Widget Reference 1237
SetMaxLetters
Sets the maximum number of text characters allowed in the edit box.
EditBox:SetMaxLetters(maxLetters)
Attempts to type more than this number into the edit box will produce no
results; programmatically inserting text or setting the edit box’s text will
truncate input to the maximum length.
Arguments:
maxLettersMaximum number of text characters allowed in the edit box, or 0
for no limit (number)
SetMultiLine
Sets whether the edit box shows more than one line of text.
EditBox:SetMultiLine(multiLine)
When in multi-line mode, the edit box’s height is determined by the number of
lines shown and cannot be set directlyenclosing the edit box in a
ScrollFrame may prove useful in such cases.
Arguments:
multiLineTrue to allow the edit box to display more than one line of text;
false for single-line display (boolean)
SetNumber
Sets the contents of the edit box to a number.
EditBox:SetNumber(num)
Arguments:
numNew numeric content for the edit box (number)
SetNumeric
Sets whether the edit box only accepts numeric input.
EditBox:SetNumeric(enable)
Note: an edit box in numeric mode only accepts numeral inputall other
characters, including those commonly used in numeric representations (such
as .,Eand -) are not allowed.
Arguments:
enableTrue to allow only numeric input; false to allow any text (boolean)
SetPassword
Sets whether the text entered in the edit box is masked.
EditBox:SetPassword(enable)
Arguments:
enableTrue to mask text entered in the edit box with asterisk
characters (*); false to show the actual text entered (boolean)
1238 Part IV Reference
SetText
Sets the edit box’s text contents.
EditBox:SetText(“text“)
Arguments:
textText to be placed in the edit box (string)
SetTextInsets
Sets the insets from the edit box’s edges which determine its interactive text
area.
EditBox:SetTextInsets(left, right, top, bottom)
Arguments:
leftDistance from the left edge of the edit box to the left edge of its interac-
tive text area (in pixels) (number)
rightDistance from the right edge of the edit box to the right edge of its inter-
active text area (in pixels) (number)
topDistance from the top edge of the edit box to the top edge of its interactive
text area (in pixels) (number)
bottomDistance from the bottom edge of the edit box to the
bottom edge of its interactive text area (in pixels) (number)
ToggleInputLanguage
Switches the edit box’s language input mode.
EditBox:ToggleInputLanguage()
If the edit box is in ROMAN mode and an alternate Input Method Editor
composition mode is available (as determined by the client locale and system
settings), switches to the alternate input mode. If the edit box is in IME
composition mode, switches back to ROMAN.
AnimationGroup
An AnimationGroup is how various animations are actually applied to a region; this
is how different behaviors can be run in sequence or in parallel with each other, auto-
matically. When you pause an AnimationGroup, it tracks which of its child animations
were playing and how far advanced they were, and resumes them from that point.
An Animation in a group has an order from 1 to 100, which determines when it
plays; once all animations with order 1 have completed, including any delays, the
AnimationGroup starts all animations with order 2.
An AnimationGroup can also be set to loop, either repeating from the beginning
or playing backward back to the beginning. An AnimationGroup has an OnLoop
handler that allows you to call your own code back whenever a loop completes. The
:Finish() method stops the animation after the current loop has completed, rather
than immediately.
AnimationGroup has all the methods from ScriptObject and ParentedObject, plus
the following:
CreateAnimation
Creates an Animation as a child of this group.
Chapter 29 Widget Reference 1239
animation = AnimationGroup:CreateAnimation(“animationType“ [,i
“name“ [, “inheritsFrom“]])
Arguments:
animationTypeType of Animation object to be created (see widgets hierar-
chy for available subtypes) (string)
name (optional)Global name to use for the new animation (string)
inheritsFrom (optional)A template from which to inherit (string)
Returns:
animationThe newly created animation (animation)
Finish
Causes animations within the group to complete and stop.
AnimationGroup:Finish()
If the group is playing, animations will continue until the current loop cycle is
complete before stopping. For example, in a group which manages a repeating
fade-out-fade-in animation, the associated object will continue to fade
completely back in, instead of the animation stopping and the object instantly
switching from partial opacity to full opacity instantly. Does nothing if this
group is not playing.
To instantly stop an animation, see AnimationGroup:Stop().
GetAnimations
Returns a list of animations belonging to the group.
... = AnimationGroup:GetAnimations()
Returns:
...A list of Animation objects belonging to the animation group
(list)
GetDuration
Returns the duration of a single loop cycle for the group, as determined by its
child animations.
duration = AnimationGroup:GetDuration()
Total duration is based on the durations, delays and order of child animations;
see example for details.
Returns:
durationTotal duration of all child animations (in seconds)
(number)
Example:
<AnimationGroup name=“Pulse“>
<Alpha name=“$parentIn“ change=“1“ duration=“0.1“/>
<Alpha name=“$parentOut“ change=“-1“ duration=“1.5“/>
</AnimationGroup>
-- contains two animations which are implicitly ordered, so
-- group duration is the sum of the animation durations: 1.6 sec
<AnimationGroup name=“Alarm“>
1240 Part IV Reference
<Alpha name=“$parentIn“ change=“1“ duration=“0.5“ order=“1“/>
<Rotation name=“$parentJiggleLeft“ degrees=“-15“ duration=“0.25“ i
startDelay=“0.35“ order=“1“/>
<Rotation name=“$parentJiggleRight“ degrees=“30“ duration=“0.5“ i
order=“2“/>
<Rotation name=“$parentJiggleStop“ degrees=“-15“ duration=“0.25“ i
endDelay=“0.25“ order=“3“/>
<Alpha name=“$parentOut“ change=“-1“ duration=“0.5“ order=“4“/>
</AnimationGroup>
-- contains delays and multiple animations, some of which are
-- concurrent, so group duration is the maximum duration (including
-- delay) of concurrent animations plus the sum of durations and
-- delays for sequential animations:
-- max(0.5, 0.25 + 0.35) + 0.5 + (0.25 + 0.25) + 0.5 = 2.1 sec
GetInitialOffset
Returns the starting static translation for the animated region.
x, y = AnimationGroup:GetInitialOffset()
Returns:
xHorizontal distance to offset the animated region (in pixels) (number)
yVertical distance to offset the animated region (in pixels) (number)
GetLoopState
Returns the current loop state of the group.
loopState = AnimationGroup:GetLoopState()
Returns:
loopStateLoop state of the animation group (string)
FORWARD - In transition from the start state to the final state
NONE - Not looping
REVERSE - In transition from the final state back to the start state
GetLooping
Returns the looping behavior of the group.
loopType = AnimationGroup:GetLooping()
Returns:
loopTypeLooping type for the animation group (string)
BOUNCE - Repeatedly animates forward from the initial state to the final state
then backwards to the initial state
NONE - No looping; animates from the initial state to the final state once and
stops
REPEAT - Repeatedly animates forward from the initial state to the final state
(instantly resetting from the final state to the initial state between repetitions)
GetMaxOrder
Returns the highest order amongst the animations in the group.
maxOrder = AnimationGroup:GetMaxOrder()
Chapter 29 Widget Reference 1241
Returns:
maxOrderHighest ordering value (see Animation:GetOrder())oftheani-
mations in the group (number)
GetProgress
Returns the current state of the animation group’s progress.
progress = AnimationGroup:GetProgress()
Returns:
progressValue indicating the current state of the group anima-
tion: between 0.0 (initial state, child animations not yet started)
and 1.0 (final state, all child animations complete) (number)
IsDone
Returns whether the group has finished playing.
done = AnimationGroup:IsDone()
Only valid in the OnFinished and OnUpdate handlers, and only applies if the
animation group does not loop.
Returns:
doneTrue if the group has finished playing; false otherwise (boolean)
IsPaused
Returns whether the group is paused.
paused = AnimationGroup:IsPaused()
Returns:
pausedTrue if animation of the group is currently paused; false otherwise
(boolean)
IsPendingFinish
Returns whether or not the animation group is pending finish.
isPending = AnimationGroup:IsPendingFinish()
Returns:
isPendingWhether or not the animation group is currently pending a
finish command. Since the Finish() method does not immediately stop
the animation group, this method can be used to test if Finish() has been
called and the group will finish at the end of the current loop. (boolean)
IsPlaying
Returns whether the group is playing.
playing = AnimationGroup:IsPlaying()
Returns:
playingTrue if the group is currently animating; false otherwise (boolean)
Pause
Pauses animation of the group.
AnimationGroup:Pause()
1242 Part IV Reference
Unlike with AnimationGroup:Stop(), the animation is paused at its current
progress state (e.g. in a fade-out-fade-in animation, the element will be at
partial opacity) instead of reset to the initial state; animation can be resumed
with AnimationGroup:Play().
Play
Starts animating the group.
AnimationGroup:Play()
If the group has been paused, animation resumes from the paused state;
otherwise animation begins at the initial state.
SetInitialOffset
Sets a static translation for the animated region.
AnimationGroup:SetInitialOffset(x, y)
This translation is only used while the animation is playing.
For example, applying an initial offset of 0,-50 to an animation group which
fades the PlayerPortrait in and out would cause the portrait image to jump
down 50 pixels from its normal position when the animation begins playing,
and return to its initial position when the animation is finished or stopped.
Arguments:
xHorizontal distance to offset the animated region (in pixels) (number)
yVertical distance to offset the animated region (in pixels) (number)
SetLooping
Sets the looping behavior of the group.
AnimationGroup:SetLooping(“loopType“)
Arguments:
loopTypeLooping type for the animation group (string)
BOUNCE - Repeatedly animates forward from the initial state to the final state
then backwards to the initial state
NONE - No looping; animates from the initial state to the final state once and
stops
REPEAT - Repeatedly animates forward from the initial state to the final state
(instantly resetting from the final state to the initial state between repetitions)
Stop
Stops animation of the group.
AnimationGroup:Stop()
Unlike with AnimationGroup:Pause(), the animation is reset to the initial
state (e.g. in a fade-out-fade-in animation, the element will be instantly
returned to full opacity) instead of paused at its current progress state.
Chapter 29 Widget Reference 1243
Animation
Animations are used to change presentations or other characteristics of a frame or
other region over time. The Animation object will take over the work of calling code
over time, or when it is done, and tracks how close the animation is to completion.
The Animation type doesn’t create any visual effects by itself, but it does provide
an OnUpdate handler that you can use to support specialized time-sensitive behaviors
that aren’t provided by the transformations descended from Animations. In addition
to tracking the passage of time through an elapsed argument, you can query the
animation’s progress as a 0-1 fraction to determine how you should set your behavior.
You can also change how the elapsed time corresponds to the progress by changing
the smoothing, which creates acceleration or deceleration, or by adding a delay to the
beginning or end of the animation.
You can also use an Animation as a timer, by setting the Animation’s OnFinished
script to trigger a callback and setting the duration to the desired time.
Animation has all the methods from ScriptObject and ParentedObject, plus the
following:
GetDuration
Returns the time for the animation to progress from start to finish.
duration = Animation:GetDuration()
Returns:
durationTime for the animation to progress from start to finish (in seconds)
(number)
GetElapsed
Returns the amount of time since the animation began playing.
elapsed = Animation:GetElapsed()
This amount includes start and end delays.
Returns:
elapsedAmount of time since the animation began playing (in seconds)
(number)
GetEndDelay
Returns the amount of time the animation delays after finishing.
delay = Animation:GetEndDelay()
A later animation in an animation group will not begin until after the end
delay period of the preceding animation has elapsed.
Returns:
delayTime the animation delays after finishing (in seconds) (number)
GetMaxFramerate
Returns the maximum number of times per second that the animation will
update its progress.
framerate = Animation:GetMaxFramerate()
1244 Part IV Reference
Does not necessarily reflect the running framerate of the animation in progress;
World of Warcraft itself may be running at a lower framerate.
Returns:
framerateMaximum number of times per second that the animation will
update its progress (number)
GetOrder
Returns the order of the animation within its parent group.
order = Animation:GetOrder()
When the parent AnimationGroup plays, Animations with a lower order
number are played before those with a higher number. Animations with the
same order number are played at the same time.
Returns:
orderPosition at which the animation will play relative to others in its group
(between 0 and 100) (number)
GetProgress
Returns the progress of the animation (ignoring start and end delay).
progress = Animation:GetProgress()
When using a generic Animation object to animate effects not handled by the
built-in Animation subtypes, this method should be used for updating effects
in the animation’s OnUpdate handler, as it properly accounts for smoothing
and delays managed by the Animation object.
Returns:
progressProgress of the animation: between 0.0 (at start) and 1.0 (at end)
(number)
GetProgressWithDelay
Returns the progress of the animation and associated delays.
progress = Animation:GetProgressWithDelay()
Returns:
progressProgress of the animation and its delays: between 0.0
(at start of start delay) and 1.0 (at end of end delay) (number)
GetRegionParent
Returns the Region object on which the animation operates.
region = Animation:GetRegionParent()
Returns:
regionReference to the Region object on which the animation operates (i.e.
the parent of the animation’s parent AnimationGroup). (region,Region)
GetSmoothProgress
Returns the progress of an animation, ignoring smoothing effects.
progress = Animation:GetSmoothProgress()
Chapter 29 Widget Reference 1245
The value returned by this method increases linearly with time while the
animation is playing, while the value returned by
Animation:GetProgress() may change at a different rate if the animation’s
smoothing type is set to a value other than NONE.
Returns:
progressProgress of the animation: between 0.0 (at start) and 1.0 (at end)
(number)
GetSmoothing
Returns the smoothing type for the animation.
smoothType = Animation:GetSmoothing()
This setting affects the rate of change in the animation’s progress value as it plays.
Returns:
smoothTypeType of smoothing for the animation (string)
IN - Initially progressing slowly and accelerating towards the end
IN_OUT - Initially progressing slowly and accelerating towards the middle,
then slowing down towards the end
NONE - Progresses at a constant rate from beginning to end
OUT - Initially progressing quickly and slowing towards the end
GetStartDelay
Returns the amount of time the animation delays before its progress begins.
delay = Animation:GetStartDelay()
Returns:
delayAmount of time the animation delays before its progress begins (in sec-
onds) (number)
IsDelaying
Returns whether the animation is currently in the middle of a start or end
delay.
delaying = Animation:IsDelaying()
Returns:
delayingTrue if the animation is currently in its start or end
delay period; false if the animation is currently between its start
and end periods (or has none) or is not playing (boolean)
IsDone
Returns whether the animation has finished playing.
done = Animation:IsDone()
Returns:
doneTrue if the animation is finished playing; otherwise false (boolean)
IsPaused
Returns whether the animation is currently paused.
paused = Animation:IsPaused()
1246 Part IV Reference
Returns:
pausedTrue if the animation is currently paused; false otherwise (boolean)
IsPlaying
Returns whether the animation is currently playing.
playing = Animation:IsPlaying()
Returns:
playingTrue if the animation is currently playing; otherwise false
(boolean)
IsStopped
Returns whether the animation is currently stopped.
stopped = Animation:IsStopped()
Returns:
stoppedTrue if the animation is currently stopped; otherwise false
(boolean)
Pause
Pauses the animation.
Animation:Pause()
Unlike with Animation:Stop(), the animation is paused at its current
progress state (e.g. in a fade-out-fade-in animation, the element will be at
partial opacity) instead of reset to the initial state; animation can be resumed
with Animation:Play().
Play
Plays the animation.
Animation:Play()
If the animation has been paused, it resumes from the paused state; otherwise
the animation begins at its initial state.
SetDuration
Sets the time for the animation to progress from start to finish.
Animation:SetDuration(duration)
Arguments:
durationTime for the animation to progress from start to finish (in seconds)
(number)
SetEndDelay
Sets the amount of time for the animation to delay after finishing.
Animation:SetEndDelay(delay)
A later animation in an animation group will not begin until after the end
delay period of the preceding animation has elapsed.
Arguments:
delayTime for the animation to delay after finishing (in seconds) (number)
Chapter 29 Widget Reference 1247
SetMaxFramerate
Sets the maximum number of times per second for the animation to update its
progress.
Animation:SetMaxFramerate(framerate)
Useful for limiting the amount of CPU time used by an animation. For
example, if an UI element is 30 pixels square and is animated to double in size
in 1 second, any visible increase in animation quality if WoW is running faster
than 30 frames per second will be negligible. Limiting the animation’s
framerate frees CPU time to be used for other animations or UI scripts.
Arguments:
framerateMaximum number of times per second for the animation to
update its progress, or 0to run at the maximum possible framerate (number)
SetOrder
Sets the order for the animation to play within its parent group.
Animation:SetOrder(order)
When the parent AnimationGroup plays, Animations with a lower order
number are played before those with a higher number. Animations with the
same order number are played at the same time.
Arguments:
orderPosition at which the animation should play relative to others in its
group (between 0 and 100) (number)
SetParent
Sets the parent for the animation.
Animation:SetParent(animGroup) or Animation:SetParent(“animGroupName“)
If the animation was not already a child of the parent, the parent will insert the
animation into the proper order amongst its children.
Arguments:
animGroupThe animation group to set as the parent of this animation
(animgroup, AnimationGroup)
animGroupNameThe name of the animation group to set as the parent of this
animation (string)
SetSmoothing
Sets the smoothing type for the animation.
Animation:SetSmoothing(“smoothType“)
This setting affects the rate of change in the animation’s progress value as it
plays.
Arguments:
smoothTypeType of smoothing for the animation (string)
IN - Initially progressing slowly and accelerating towards the end
1248 Part IV Reference
IN_OUT - Initially progressing slowly and accelerating towards the middle,
then slowing down towards the end
NONE - Progresses at a constant rate from beginning to end
OUT - Initially progressing quickly and slowing towards the end
SetStartDelay
Sets the amount of time for the animation to delay before its progress begins.
Animation:SetStartDelay(delay)
Start delays can be useful with concurrent animations in a group: see example
for details.
Arguments:
delayAmount of time for the animation to delay before its progress begins (in
seconds) (number)
Example:
local group = PlayerPortrait:CreateAnimationGroup()
local embiggen = group:CreateAnimation(“Scale“)
embiggen:SetDuration(0.5)
embiggen:SetOrder(1)
embiggen:SetScale(2,2)
local rotate = group:CreateAnimation(“Rotation“)
rotate:SetDuration(1)
rotate:SetOrder(1)
rotate:SetDegrees(720)
local shrink = group:CreateAnimation(“Scale“)
shrink:SetDuration(0.5)
shrink:SetOrder(1)
shrink:SetStartDelay(0.5)
shrink:SetScale(0.5, 0.5)
-- causes the player portrait to spin while expanding and contracting
group:Play()
Stop
Stops the animation.
Animation:Stop()
Also resets the animation to its initial state.
Path
APath animation combines multiple transitions into a single control path with multiple
ControlPoints. The offsets of each control point are set relative to the origin of the region,
rather than relative to the current position of the animation. The following example
will animate the player’s portrait in a box to the bottom right of its original position:
local group = PlayerPortrait:CreateAnimationGroup(“PortraitBox“)
local path = group:CreateAnimation(“Path“)
local a = path:CreateControlPoint()
local b = path:CreateControlPoint()
Chapter 29 Widget Reference 1249
local c = path:CreateControlPoint()
local d = path:CreateControlPoint()
path:SetCurve(“SMOOTH“)
path:SetDuration(4.0)
a:SetOffset(70, 0)
a:SetOrder(1)
b:SetOffset(75, -75)
b:SetOrder(2)
c:SetOffset(0, -75)
c:SetOrder(3)
d:SetOffset(0, 0)
d:SetOrder(4)
PortraitBox:Play()
Path has all the methods from Animation, plus the following:
CreateControlPoint
Creates a new control point for the given path.
Path:CreateControlPoint([“name“ [, “template“ [, order]]])
Arguments:
name (optional)The name of the object (string)
template (optional)The template from which the new point should inherit
(string)
order (optional)The order of the new control point (number)
GetControlPoints
Returns the control points that belong to a given path.
... = Path:GetControlPoints()
Returns:
...A list of ControlPoint objects that belong to the given path.
(ControlPoint)
GetCurve
Returns the curveType of the given path.
curveType = Path:GetCurve()
Returns:
curveTypeThecurvetypeforthegivenpath(string)
NONE - The control points are used literally.
SMOOTH - The control points are used with a smoothing function that may give
a more pleasing animation.
GetMaxOrder
Returns the maximum order of the control points belonging to a given path.
max = Path:GetMaxOrder()
Returns:
maxThe maximum order of the control points belonging to the given path.
This can be used to determine how many points a path contains. (number)
1250 Part IV Reference
SetCurve
Sets the curve type for the path animation.
Path:SetCurve(“curveType“)
Arguments:
curveTypeThecursetypeforthegivenpath(string)
NONE - The control points are used literally.
SMOOTH - The control points are used with a smoothing function that may give
a more pleasing animation.
ControlPoint
AControlPoint is a special type of UIObject that represent a point in a Path
Animation. The offset for each control point is from the origin of the animated Region.
See Path for more details.
ControlPoint has all the methods from ParentedObject, plus the following:
GetOffset
Returns the offset for the control point.
x, y = ControlPoint:GetOffset()
Returns:
xThe x coordinate offset for the control point (number)
yThe y coordinate offset for the control point (number)
GetOrder
Returns the order of the control point in a path animation.
order = ControlPoint:GetOrder()
When the parent path animation plays, the control points with a lower number
are traversed before those with a higher number. Control points must have
distinct order indices, and these will be assigned automatically as new points
are created.
Returns:
orderPosition at which the control point will be traversed relative
to others in the same path animation (between 0 and 100) (number)
SetOffset
Sets the offset for the control point.
ControlPoint:SetOffset(x, y)
Arguments:
xThe x coordinate offset for the control point (number)
yThe y coordinate offset for the control point (number)
SetOrder
Sets the order of the control point in a path animation.
ControlPoint:SetOrder(order)
When the parent path animation plays, the control points with a lower number
are traversed before those with a higher number. Control points must have
Chapter 29 Widget Reference 1251
distinct order indices, and these will be assigned automatically as new points
are created.
Arguments:
orderPosition at which the control point will be traversed relative
to others in the same path animation (between 0 and 100) (number)
SetParent
Sets a new path animation parent for a control point.
ControlPoint:SetParent([path [, order]]) or i
ControlPoint:SetParent([“path“ [, order]])
Arguments:
path (optional)The path object to be set as parent. (table)
path (optional)The name of a path object to be set as parent. (string)
order (optional)The order index to set for the control point in the new parent
animation. (number)
Rotation
Rotation is an Animation that automatically applies an affine rotation to the region
being animated. You can set the origin around which the rotation is being done, and
the angle of rotation in either degrees or radians.
Rotation animations have no effect on FontStrings.
Rotation has all the methods from Animation, plus the following:
GetDegrees
Returns the animation’s rotation amount (in degrees).
degrees = Rotation:GetDegrees()
Returns:
degreesAmount by which the region rotates over the animation’s duration
(in degrees; positive values for counter-clockwise rotation, negative for clock-
wise) (number)
GetOrigin
Returns the rotation animation’s origin point.
point, xOffset, yOffset = Rotation:GetOrigin()
During a rotation animation, the origin point remains in place while the
positions of all other points in the scaled region are moved according to the
rotation amount.
Returns:
pointAnchor point for the rotation origin (string, anchorPoint)
xOffsetHorizontal distance from the anchor point to the rotation origin (in
pixels) (number)
yOffsetVertical distance from the anchor point to the rotation origin (in pix-
els) (number)
GetRadians
Returns the animation’s rotation amount (in radians).
radians = Rotation:GetRadians()
1252 Part IV Reference
Returns:
radiansAmount by which the region rotates over the animation’s duration
(in radians; positive values for counter-clockwise rotation, negative for clock-
wise) (number)
SetDegrees
Sets the animation’s rotation amount (in degrees).
Rotation:SetDegrees(degrees)
Arguments:
degreesAmount by which the region should rotate over the animation’s
duration (in degrees; positive values for counter-clockwise rotation, negative for
clockwise) (number)
SetOrigin
Sets the rotation animation’s origin point.
Rotation:SetOrigin(“point“, xOffset, yOffset)
During a rotation animation, the origin point remains in place while the
positions of all other points in the scaled region are moved according to the
rotation amount.
Arguments:
pointAnchor point for the rotation origin (string, anchorPoint)
xOffsetHorizontal distance from the anchor point to the rotation origin (in
pixels) (number)
yOffsetVertical distance from the anchor point to the rotation origin (in pix-
els) (number)
SetRadians
Sets the animation’s rotation amount (in radians).
Rotation:SetRadians(radians)
Arguments:
radiansAmount by which the region should rotate over the animation’s
duration (in radians; positive values for counter-clockwise rotation, negative for
clockwise) (number)
Scale
Scale is an Animation type that automatically applies an affine scalar transformation
to the region being animated as it progresses. You can set both the multiplier by which
it scales, and the point from which it is scaled.
Scale animations are not applied to FontStrings.
Scale has all the methods from Animation, plus the following:
GetOrigin
Returns the scale animation’s origin point.
point, xOffset, yOffset = Scale:GetOrigin()
Chapter 29 Widget Reference 1253
During a scale animation, the origin point remains in place while the positions
of all other points in the scaled region are moved according to the scale factor.
Returns:
pointAnchor point for the scale origin (string, anchorPoint)
xOffsetHorizontal distance from the anchor point to the scale origin (in pix-
els) (number)
yOffsetVertical distance from the anchor point to the scale origin (in pixels)
(number)
GetScale
Returns the animation’s scaling factors.
xFactor, yFactor = Scale:GetScale()
At the end of the scale animation, the animated region’s dimensions are equal
to its initial dimensions multiplied by its scaling factors.
Returns:
xFactorHorizontal scaling factor (number)
yFactorVertical scaling factor (number)
SetOrigin
Sets the scale animation’s origin point.
Scale:SetOrigin(“point“, xOffset, yOffset)
During a scale animation, the origin point remains in place while the positions
of all other points in the scaled region are moved according to the scale factor.
Arguments:
pointAnchor point for the scale origin (string, anchorPoint)
xOffsetHorizontal distance from the anchor point to the scale origin (in pix-
els) (number)
yOffsetVertical distance from the anchor point to the scale origin (in pixels)
(number)
SetScale
Sets the animation’s scaling factors.
Scale:SetScale(xFactor, yFactor)
At the end of the scale animation, the animated region’s dimensions are equal
to its initial dimensions multiplied by its scaling factors.
Arguments:
xFactorHorizontal scaling factor (number)
yFactorVertical scaling factor (number)
Translation
Translation is an Animation type that applies an affine translation to its affected region
automatically as it progresses. You can set the offset in both the X and Y dimensions.
Translations can be applied normally to both Textures and FontStrings.
1254 Part IV Reference
Translation has all the methods from Animation, plus the following:
GetOffset
Returns the animation’s translation offsets.
xOffset, yOffset = Translation:GetOffset()
Returns:
xOffsetDistance away from the left edge of the screen (in pixels)
to move the region over the animation’s duration (number)
yOffsetDistance away from the bottom edge of the screen (in pix-
els) to move the region over the animation’s duration (number)
SetOffset
Sets the animation’s translation offsets.
Translation:SetOffset(xOffset, yOffset)
Arguments:
xOffsetDistance away from the left edge of the screen (in pixels)
to move the region over the animation’s duration (number)
yOffsetDistance away from the bottom edge of the screen (in pix-
els) to move the region over the animation’s duration (number)
Alpha
Alpha is a type of animation that automatically changes the transparency level of its
attached region as it progresses. You can set the degree by which it will change the
alpha as a fraction; for instance, a change of -1 will fade out a region completely.
Alpha has all the methods from Animation, plus the following:
GetChange
Returns the animation’s amount of alpha (opacity) change.
change = Alpha:GetChange()
A region’s alpha value can be between 0 (fully transparent) and 1 (fully
opaque); thus, an animation which changes alpha by 1 will always increase the
region to full opacity, regardless of the region’s existing alpha (and an
animation whose change amount is -1 will reduce the region to fully
transparent).
Returns:
changeAmount by which the region’s alpha value changes over the anima-
tion’s duration (between -1 and 1)(number)
SetChange
Sets the animation’s amount of alpha (opacity) change.
Alpha:SetChange(change)
A region’s alpha value can be between 0 (fully transparent) and 1 (fully
opaque); thus, an animation which changes alpha by 1 will always increase the
Chapter 29 Widget Reference 1255
region to full opacity, regardless of the region’s existing alpha (and an
animation whose change amount is -1 will reduce the region to fully
transparent).
Arguments:
changeAmount by which the region’s alpha value should change
over the animation’s duration (between -1and 1)(number)
Widget Scripts
Widget scripts allow you to respond to user interaction and other types of widget
events (such as a frame being shown or hidden). This section details the various widget
scripts that are available, and the list of widget types for which each script is valid.
OnAnimFinished
Run when the model’s animation finishes.
OnAnimFinished(self)
Only run for models which do not repeat their animations (e.g. the model used
for the ‘‘icon falling into bag’’ animation which appears above the default UI’s
bag buttons when looting or purchasing items).
Only used for animations internal to Model objects; for widget animations, see
OnFinished.
Arguments:
selfReference to the widget for which the script was run (model)
This widget script is defined for the following widget types: DressUpModel,
Model, PlayerModel, TabardModel
OnAttributeChanged
Run when a frame attribute is changed.
OnAttributeChanged(self, “name“, value)
Attributes are used by the secure template system; see here for more details.
Arguments:
selfReference to the widget for which the script was run (frame)
nameName of the changed attribute, always lower case (string)
valueNew value of the attribute (value)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnChar
Run for each text character typed in the frame.
OnChar(self, “text“)
1256 Part IV Reference
This script is run for each character produced, not necessarily each key pressed.
For example, on Windows computers, holding ALT while typing 233 on the
number pad will enter the character ‘‘´
e’’; the OnChar script is run with ´
e“ as
the second argument. Note that WoW uses the Unicode (UTF-8) encoding, so a
string containing a single visible character may have a length greater than 1.
If a block of text is inserted into a frame (e.g. when inserting a hyperlink), the
script is run once with the entire text as the second argument. Only run for
EditBoxes or frames for which keyboard input is enabled.
Arguments:
selfReference to the widget for which the script was run (frame)
textThe text entered (string)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnCharComposition
Run when the edit box’s input composition mode changes.
OnCharComposition(self, “text“)
Primarily used in international clients that can use IME composition.
Arguments:
selfReference to the widget for which the script was run (frame)
textPartial text in the character composition mode (string)
This widget script is defined for the following widget types: EditBox
OnClick
Run when the button is clicked.
OnClick(self, “button“, down)
By default, this script is only run for the left mouse button’s ‘‘up’’ action; the
:RegisterForClicks() method can be called to enable the button to respond
to other buttons and actions.
Using or hooking the OnClick handler may not always be useful or desirable;
the PreClick and PostClick scripts are provided for such purposes.
Moving the mouse away from the button before releasing it will not run the
PreClick/OnClick/PostClick handlers, but will still run the OnMouseUp
handler.
Arguments:
selfReference to the widget for which the script was run (button)
buttonName of the mouse button responsible for the click action (string)
downTrue for a mouse button down action; false for button up or other
actions (boolean)
Chapter 29 Widget Reference 1257
Example:
-- Illustrates the timing of mouse script handlers when clicking
-- a button
local b = CreateFrame(“Button“, “TestButton“, UIParent, i
“UIPanelButtonTemplate2“)
b:SetPoint(“CENTER“)
b:RegisterForClicks(“AnyUp“, “AnyDown“)
local upDown = { [false] = “Up“, [true] = “Down“ }
local function show(text, color)
DEFAULT_CHAT_FRAME:AddMessage(text, color, color, color)
end
local color
b:SetScript(“OnMouseDown“, function(self, button)
color = .60
show(format(“OnMouseDown: %s“, button), color, color, color)
end)
b:SetScript(“OnMouseUp“, function(self, button)
color = .60
show(format(“OnMouseUp: %s“, button), color, color, color)
end)
b:SetScript(“OnClick“, function(self, button, down)
color = color + 0.1
show(format(“OnClick: %s %s“, button, upDown[down]), color, i
color, color)
end)
b:SetScript(“PreClick“, function(self, button, down)
color = color + 0.1
show(format(“PreClick: %s %s“, button, upDown[down]), color, i
color, color)
end)
b:SetScript(“PostClick“, function(self, button,down)
color = color + 0.1
show(format(“PostClick: %s %s“, button, upDown[down]), color, i
color, color)
end)
This widget script is defined for the following widget types: Button,
CheckButton
OnColorSelect
Run when the color select frame’s color selection changes.
OnColorSelect(self, r, g, b)
Arguments:
selfReference to the widget for which the script was run (frame)
rRed component of the selected color (0.0 - 1.0) (number)
gGreen component of the selected color (0.0 - 1.0) (number)
bBlue component of the selected color (0.0 - 1.0) (number)
This widget script is defined for the following widget types: ColorSelect
1258 Part IV Reference
OnCursorChanged
Run when the position of the text insertion cursor in the edit box changes.
OnCursorChanged(self, x, y, width, height)
Also run when the edit box gains or loses keyboard focus.
Arguments:
selfReference to the widget for which the script was run (editbox)
xHorizontal position of the cursor relative to the top left corner of the edit box
(in pixels) (number)
yVertical position of the cursor relative to the top left corner of the edit box (in
pixels) (number)
widthWidth of the cursor graphic (in pixels) (number)
heightHeight of the cursor graphic (in pixels); matches the height of a line of
text in the edit box (number)
This widget script is defined for the following widget types: EditBox
OnDisable
Run when the frame is disabled.
OnDisable(self)
Arguments:
selfReference to the widget for which the script was run (frame)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnDoubleClick
Run when the button is double-clicked.
OnDoubleClick(self, “button“)
Run if the mouse button is clicked twice within 0.3 seconds. (The PreClick,
OnClick and PostClick handlers are run for the first click but not the
second.)
Arguments:
selfReference to the widget for which the script was run (button)
buttonName of the mouse button responsible for the click action (string)
This widget script is defined for the following widget types: Button,
CheckButton
OnDragStart
Run when the mouse is dragged starting in the frame.
OnDragStart(self, “button“)
Chapter 29 Widget Reference 1259
In order for a drag action to begin, the mouse button must be pressed down
within the frame and moved more than several (10) pixels in any direction
without being released.
Arguments:
selfReference to the widget for which the script was run (button)
buttonName of the mouse button responsible for the drag action (string)
Example:
-- Illustrates script handlers involved in dragging. Dragging to or
-- from either button will display messages detailing the process.
local nextNum = 1
local last
local handlers = {
“OnMouseDown“, “OnMouseUp“, “OnDragStart“, “OnDragStop“, i
“OnReceiveDrag“
}
local function CreateButton()
local curNum = nextNum
local b = CreateFrame(“Button“, “Test“..curNum, UIParent, i
“UIPanelButtonTemplate2“)
if curNum == 1 then
b:SetPoint(“CENTER“)
else
b:SetPoint(“LEFT“, last, “RIGHT“, 5, 0)
end
b:SetText(curNum)
b:RegisterForDrag(“LeftButton“, “RightButton“)
for _, handler in ipairs(handlers) do
b:SetScript(handler, function(self, button)
button = button and “, “..button or ““
DEFAULT_CHAT_FRAME:AddMessage(format(“%s: %d%s“, handler, i
curNum, button))
end)
end
nextNum = nextNum + 1
last = b
end
CreateButton()
CreateButton()
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnDragStop
Run when the mouse button is released after a drag started in the frame.
OnDragStop(self)
1260 Part IV Reference
This script is run only for drags started within the frame, regardless of the
cursor’s position at the end of the drag. For further details, see the example
under OnDragStart.
Arguments:
selfReference to the widget for which the script was run (button)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnEditFocusGained
Run when the edit box becomes focused for keyboard input.
OnEditFocusGained(self)
Arguments:
selfReference to the widget for which the script was run (editbox)
This widget script is defined for the following widget types: EditBox
OnEditFocusLost
Run when the edit box loses keyboard input focus.
OnEditFocusLost(self)
Arguments:
selfReference to the widget for which the script was run (exitbox)
This widget script is defined for the following widget types: EditBox
OnEnable
Run when the frame is enabled.
OnEnable(self)
Arguments:
selfReference to the widget for which the script was run (frame)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnEnter
Run when the mouse cursor enters the frame’s interactive area.
OnEnter(self, motion)
Note that a frame’s mouse-interactive area can be changed via its
:SetHitRectInsets() method.
Arguments:
selfReference to the widget for which the script was run (frame)
Chapter 29 Widget Reference 1261
motionTrue if the handler is being run due to actual mouse move-
ment; false if the cursor entered the frame due to other circumstances
(such as the frame being created underneath the cursor) (boolean)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnEnterPressed
Run when the Enter (or Return) key is pressed while the edit box has keyboard
focus.
OnEnterPressed(self)
Arguments:
selfReference to the widget for which the script was run (editbox)
This widget script is defined for the following widget types: EditBox
OnEscapePressed
Run when the Escape key is pressed while the edit box has keyboard focus.
OnEscapePressed(self)
By default, an EditBox provides no way to clear keyboard input focus (though
clicking in another edit box will focus it instead)providing an
OnEscapePressed handler to call :ClearFocus() (or inheriting from the
default UI’s InputBoxTemplate, which does so) may prove
useful.
Arguments:
selfReference to the widget for which the script was run (editbox)
This widget script is defined for the following widget types: EditBox
OnEvent
Run whenever an event fires for which the frame is registered.
OnEvent(self, “event“, ...)
In order for this script to be run, the frame must be registered for at least one
event via its :RegisterEvent() method. See the Events Reference for details
of each event.
Arguments:
selfReference to the widget for which the script was run (frame)
eventName of the event (string)
...Arguments specific to the event (list)
This widget script is defined for the following widget types: Alpha, Animation,
AnimationGroup, Button, CheckButton, ColorSelect, Cooldown,
DressUpModel, EditBox, Frame, GameTooltip, MessageFrame, Minimap,
Model, MovieFrame, Path, PlayerModel, Rotation, Scale, ScrollFrame,
1262 Part IV Reference
ScrollingMessageFrame, SimpleHTML, Slider, StatusBar, TabardModel,
Translation
OnFinished
Run when the animation (or animation group) finishes animating.
OnFinished(self, requested)
Does not run for an animation group set to loop unless the group’s :Finish()
method is called.
Arguments:
selfReference to the widget for which the script was run (animation)
requestedTrue if animation finished because of a call to AnimationGroup:
Finish();false otherwise (boolean)
This widget script is defined for the following widget types: Alpha, Animation,
AnimationGroup, Path, Rotation, Scale, Translation
OnHide
Run when the frame’s visibility changes to hidden.
OnHide(self)
This script handler runs whether the frame was directly hidden (via its
:Hide() method) or implicitly hidden due to a parent frame being hidden.
Arguments:
selfReference to the widget for which the script was run (frame)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnHorizontalScroll
Run when the scroll frame’s horizontal scroll position changes.
OnHorizontalScroll(self, offset)
Arguments:
selfReference to the widget for which the script was run (scrollframe)
offsetNew horizontal scroll position (in pixels, measured from the leftmost
scroll position) (number)
This widget script is defined for the following widget types: ScrollFrame
OnHyperlinkClick
Run when the mouse clicks a hyperlink in the scrolling message frame or
SimpleHTML frame.
OnHyperlinkClick(self, “linkData“, “link“, “button“)
This script handler is run when the mouse button is released while the mouse
cursor is over the same hyperlink text in which the mouse button was pressed.
Arguments:
selfReference to the widget for which the script was run (frame)
Chapter 29 Widget Reference 1263
linkDataEssential data (linktype:linkdata portion) of the hyperlink (e.g.
“quest:982:17“)(string)
linkComplete hyperlink text (e.g. “|cffffff00|Hquest:982:17|
h[Deep Ocean, Vast Sea]|h|r“)(string, hyperlink)
buttonName of the mouse button responsible for the click action (string)
Example:
-- Print information about a clicked hyperlink
local someMessageFrame = WowLuaFrameOutput
someMessageFrame:SetScript(“OnHyperlinkClick“, function(self, i
linkData, link, button)
self:AddMessage(format(“You clicked on %s with %s“, link, button))
end)
This widget script is defined for the following widget types:
ScrollingMessageFrame, SimpleHTML
OnHyperlinkEnter
Run when the mouse moves over a hyperlink in the scrolling message frame or
SimpleHTML frame.
OnHyperlinkEnter(self, “linkData“, “link“)
Arguments:
selfReference to the widget for which the script was run (frame)
linkDataEssential data (linktype:linkdata portion) of the hyperlink (e.g.
“quest:982:17“)(string)
linkComplete hyperlink text (e.g. “|cffffff00|Hquest:982:17|
h[Deep Ocean, Vast Sea]|h|r“)(string, hyperlink)
Example:
-- Prints data about the hyperlink you enter in the default chat frame
DEFAULT_CHAT_FRAME:SetScript(“OnHyperlinkEnter“, function(self, i
linkData, link)
local color = link:match(“|c%x%x%x%x%x%x%x%x“) or ““
self:AddMessage(“linkData: “..linkData)
self:AddMessage(format(“link: %s%s“, color, link:gsub(“|“,“||“)))
end)
This widget script is defined for the following widget types:
ScrollingMessageFrame, SimpleHTML
OnHyperlinkLeave
Run when the mouse moves away from a hyperlink in the scrolling message
frame or SimpleHTML frame.
OnHyperlinkLeave(self, “linkData“, “link“)
Arguments:
selfReference to the widget for which the script was run (frame)
linkDataEssential data (linktype:linkdata portion) of the hyperlink (e.g.
“quest:982:17“)(string)
linkComplete hyperlink text (e.g. “|cffffff00|Hquest:982:17|h
[Deep Ocean, Vast Sea]|h|r“)(string, hyperlink)
1264 Part IV Reference
Example:
-- Prints data about the hyperlink you leave in the default chat frame
DEFAULT_CHAT_FRAME:SetScript(“OnHyperlinkLeave“, i
function(self, linkData, link)
local color = link:match(“|c%x%x%x%x%x%x%x%x“) or ““
self:AddMessage(“linkData: “..linkData)
self:AddMessage(format(“link: %s%s“, color, link:gsub(“|“,“||“)))
end)
This widget script is defined for the following widget types:
ScrollingMessageFrame, SimpleHTML
OnInputLanguageChanged
Run when the edit box’s language input mode changes.
OnInputLanguageChanged(self, “language“)
Applies to keyboard input methods, not in-game languages or client
localesonly relevant for international clients that allow multiple input
languages.
Arguments:
selfReference to the widget for which the script was run (editbox)
languageName of the new input language (see :GetInputLanguage())
(string)
This widget script is defined for the following widget types: EditBox
OnKeyDown
Run when a keyboard key is pressed if the frame is keyboard enabled.
OnKeyDown(self, “key“)
Does not run for focused EditBoxes.
Arguments:
selfReference to the widget for which the script was run (frame)
keyName of the key pressed (string,binding)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnKeyUp
Run when a keyboard key is released if the frame is keyboard enabled.
OnKeyUp(self, “key“)
Does not run for focused EditBoxes.
Arguments:
selfReference to the widget for which the script was run (frame)
keyName of the key pressed (string,binding)
Chapter 29 Widget Reference 1265
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnLeave
Run when the mouse cursor leaves the frame’s interactive area.
OnLeave(self, motion)
Note that a frame’s mouse-interactive area can be changed via its
:SetHitRectInsets() method.
Arguments:
selfReference to the widget for which the script was run (frame)
motionTrue if the handler is being run due to actual mouse move-
ment; false if the cursor left the frame due to other circumstances
(such as the frame being created underneath the cursor) (boolean)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnLoad
Runwhentheframeiscreated.
OnLoad(self)
In practice, this handler is only applicable when defined in XML (either for
frames created in XML or for XML templates inherited by dynamically created
frames). A frame created via CreateFrame() will have already run its
(non-existent) OnLoad script by the time that function returns, leaving no
opportunity to run an OnLoad handler set later.
Arguments:
selfReference to the widget for which the script was run (frame)
This widget script is defined for the following widget types: Alpha, Animation,
AnimationGroup, Button, CheckButton, ColorSelect, Cooldown,
DressUpModel, EditBox, Frame, GameTooltip, MessageFrame, Minimap,
Model, MovieFrame, Path, PlayerModel, Rotation, Scale, ScrollFrame,
ScrollingMessageFrame, SimpleHTML, Slider, StatusBar, TabardModel,
Translation
OnLoop
Run when the animation group’s loop state changes.
OnLoop(self, “loopState“)
Arguments:
selfReference to the widget for which the script was run (animgroup)
1266 Part IV Reference
loopStateToken identifying the new loop state (string)
This widget script is defined for the following widget types: AnimationGroup
OnMessageScrollChanged
Run when the scrolling message frame’s scroll position changes.
OnMessageScrollChanged(self)
AScrollingMessageFrame’s scroll position can change not only when it is
scrolled, but also when a message is added to the frame; both cases cause this
script handler to be run.
Arguments:
selfReference to the widget for which the script was run
(scrollingmessageframe)
This widget script is defined for the following widget types:
ScrollingMessageFrame
OnMinMaxChanged
Run when the slider’s or status bar’s minimum and maximum values change.
OnMinMaxChanged(self, min, max)
Run when the minimum/maximum values are set programmatically with
Slider:SetMinMaxValues() or StatusBar:SetMinMaxValues().
Arguments:
selfReference to the widget for which the script was run (frame)
minNew minimum value of the slider or the status bar (number)
maxNew maximum value of the slider or the status bar (number)
This widget script is defined for the following widget types: Slider, StatusBar
OnMouseDown
Run when a mouse button is pressed while the cursor is over the frame.
OnMouseDown(self, “button“)
For further details, see the example under OnClick.
Arguments:
selfReference to the widget for which the script was run (frame)
buttonName of the mouse button responsible for the click action (string)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnMouseUp
Run when the mouse button is released following a mouse down action in the
frame.
OnMouseUp(self, “button“)
Chapter 29 Widget Reference 1267
This script is always run for the frame which received the initial mouse button
down event (unless the frame is registered for drag actions and a drag action is
started before the button is released). For further details, see the example under
OnClick.
Arguments:
selfReference to the widget for which the script was run (frame)
buttonName of the mouse button responsible for the click action (string)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnMouseWheel
Run when the frame receives a mouse wheel scrolling action.
OnMouseWheel(self, delta)
In order for this handler to be run, the frame must be mouse wheel enabled
and the mouse cursor must be within the frame while the scroll wheel (or
equivalent device) is used.
Arguments:
selfReference to the widget for which the script was run (frame)
delta1for a scroll-up action, -1 for a scroll-down action (number)
Example:
-- Print the mousewheel delta for a button
CreateFrame(“Frame“, “test“, UIParent, “UIPanelButtonTemplate2“)
test:SetPoint(“CENTER“)
test:EnableMouseWheel(true)
test:SetScript(“OnMouseWheel“, function(self, delta)
DEFAULT_CHAT_FRAME:AddMessage(delta)
end)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnMovieFinished
Run when a movie frame’s movie ends.
OnMovieFinished(self)
Arguments:
selfReference to the widget for which the script was run (movieframe)
This widget script is defined for the following widget types: MovieFrame
1268 Part IV Reference
OnMovieHideSubtitle
Runs when the movie’s most recently displayed subtitle should be hidden.
OnMovieHideSubtitle(self)
Arguments:
selfReference to the widget for which the script was run (movieframe)
This widget script is defined for the following widget types: MovieFrame
OnMovieShowSubtitle
Runs when a subtitle for the playing movie should be displayed.
OnMovieShowSubtitle(self, “text“)
Arguments:
selfReference to the widget for which the script was run (movieframe)
textSubtitle text to be displayed (string)
This widget script is defined for the following widget types: MovieFrame
OnPause
Run when the animation (or animation group) is paused.
OnPause(self)
Arguments:
selfReference to the widget for which the script was run (animation)
This widget script is defined for the following widget types: Alpha, Animation,
AnimationGroup, Path, Rotation, Scale, Translation
OnPlay
Run when the animation (or animation group) begins to play.
OnPlay(self)
Arguments:
selfReference to the widget for which the script was run (animation)
This widget script is defined for the following widget types: Alpha, Animation,
AnimationGroup, Path, Rotation, Scale, Translation
OnReceiveDrag
Run when the mouse button is released after dragging into the frame.
OnReceiveDrag(self)
This script is run for the frame under the cursor at the end of a drag, regardless
of which started the drag. For further details, see the example under
OnDragStart.
Arguments:
selfThe frame object that this handler was called for. (frame)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
Chapter 29 Widget Reference 1269
OnScrollRangeChanged
Run when the scroll frame’s scroll position is changed.
OnScrollRangeChanged(self, xOffset, yOffset)
Only run when the scroll position changes due to changes in the scroll child
frame’s dimensions, not when :SetHorizontalScroll() or
:SetVerticalScroll() is called.
Arguments:
selfReference to the widget for which the script was run (scrollframe)
xOffsetNew horizontal scroll range (in pixels, measured from the leftmost
scroll position) (number)
yOffsetNew vertical scroll range (in pixels, measured from the topmost
scroll position) (number)
Example:
-- Set the min and max values of a scroll bar (Slider) based on
-- the scroll range
scrollFrame:SetScript(“OnScrollRangeChanged“, function(self, x, y)
verticalScrollBar:SetMinMaxValues(0, y)
end)
This widget script is defined for the following widget types: ScrollFrame
OnShow
Run when the frame becomes visible.
OnShow(self)
This script handler runs whether the frame was directly shown (via its
:Show() method) or became visible due to a parent frame being shown. The
OnShow handler is not run if the frame is implicitly shown upon its creation.
Arguments:
selfReference to the widget for which the script was run (frame)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnSizeChanged
Run when a frame’s size changes.
OnSizeChanged(self, width, height)
Arguments:
selfReference to the widget for which the script was run (frame)
widthNew width of the frame (in pixels) (number)
heightNew height of the frame (in pixels) (number)
This widget script is defined for the following widget types: Button,
CheckButton, ColorSelect, Cooldown, DressUpModel, EditBox, Frame,
1270 Part IV Reference
GameTooltip, MessageFrame, Minimap, Model, MovieFrame, PlayerModel,
ScrollFrame, ScrollingMessageFrame, SimpleHTML, Slider, StatusBar,
TabardModel
OnSpacePressed
Run when the space bar is pressed while the edit box has keyboard focus.
OnSpacePressed(self)
Arguments:
selfReference to the widget for which the script was run (editbox)
This widget script is defined for the following widget types: EditBox
OnStop
Run when the animation (or animation group) is stopped.
OnStop(self, requested)
Arguments:
selfReference to the widget for which the script was run
(animation)
requestedTrue if the animation was stopped due to a call to the animation’s
or group’s :Stop() method; false if the animation was stopped for other rea-
sons (boolean)
This widget script is defined for the following widget types: Alpha, Animation,
AnimationGroup, Path, Rotation, Scale, Translation
OnTabPressed
Run when the Tab key is pressed while the edit box has keyboard focus.
OnTabPressed(self)
Providing a handler for this script can be useful for allowing the user to switch
quickly among several edit boxes in a panel.
Arguments:
selfReference to the widget for which the script was run (editbox)
This widget script is defined for the following widget types: EditBox
OnTextChanged
Run when the edit box’s text is changed.
OnTextChanged(self, isUserInput)
This script is run both when text is typed in the edit box (for each character
entered) and when the edit box’s contents are changed via :SetText() (but
only if the text is actually changed).
Arguments:
selfReference to the widget for which the script was run (exitbox)
isUserInputTrue if the text changed due to user input; false if the text was
changed via :SetText() (boolean)
This widget script is defined for the following widget types: EditBox
Chapter 29 Widget Reference 1271
OnTextSet
Run when the edit box’s text is set programmatically.
OnTextSet(self)
Only run as a result of calling :SetText().
Arguments:
selfReference to the widget for which the script was run (editbox)
This widget script is defined for the following widget types: EditBox
OnTooltipAddMoney
Run when an amount of money should be added to the tooltip.
OnTooltipAddMoney(self, amount, maxAmount)
This happens when the tooltip is set to display an item for which an amount of
money is displayed (e.g. an item with a vendor sell price, or an equipped item
while the cursor is in item-repair mode).
Arguments:
selfReference to the widget for which the script was run (gametooltip)
amountAmount of money to be added to the tooltip (in copper) (number)
maxAmountA second amount of money to be added to the tooltip
(in copper); if non-nil, the first amount is treated as the minimum
and this amount as the maximum of a price range (number)
Example:
-- Display the amount of copper that is added to the tooltip
GameTooltip:HookScript(“OnTooltipAddMoney“, function(self, amount)
DEFAULT_CHAT_FRAME:AddMessage(format(“Money: %d“, amount))
end)
This widget script is defined for the following widget types: GameTooltip
OnTooltipCleared
Runwhenthetooltipishiddenoritscontentiscleared.
OnTooltipCleared(self)
Arguments:
selfReference to the widget for which the script was run (gametooltip)
This widget script is defined for the following widget types: GameTooltip
OnTooltipSetAchievement
Runwhenthetooltipisfilledwithinformation about an achievement.
OnTooltipSetAchievement(self)
See :SetAchievement().
Arguments:
selfReference to the widget for which the script was run (gametooltip)
This widget script is defined for the following widget types: GameTooltip
1272 Part IV Reference
OnTooltipSetDefaultAnchor
Run when the tooltip is repositioned to its default anchor location.
OnTooltipSetDefaultAnchor(self)
This happens when (for example) mousing over a unit in the 3D world.
Arguments:
selfReference to the widget for which the script was run (gametooltip)
This widget script is defined for the following widget types: GameTooltip
OnTooltipSetEquipmentSet
Run when the tooltip is filled with information about an equipment set.
OnTooltipSetEquipmentSet(self)
See :SetEquipmentSet().
Arguments:
selfReference to the widget for which the script was run (gametooltip)
This widget script is defined for the following widget types: GameTooltip
OnTooltipSetFrameStack
Run when the tooltip is filled with a list of frames under the mouse cursor.
OnTooltipSetFrameStack(self)
See :SetFrameStack().
Arguments:
selfReference to the widget for which the script was run (gametooltip)
This widget script is defined for the following widget types: GameTooltip
OnTooltipSetItem
Run when the tooltip is filled with information about an item.
OnTooltipSetItem(self)
See :GetItem() and the several GameTooltip methods for filling the tooltip
with information about items from various parts of the UI.
Arguments:
selfReference to the widget for which the script was run (gametooltip)
This widget script is defined for the following widget types: GameTooltip
OnTooltipSetQuest
Run when the tooltip is filled with information about a quest.
OnTooltipSetQuest(self)
See GameTooltip:SetHyperlink() to load the tooltip with information
about a quest.
Arguments:
selfReference to the widget for which the script was run (gametooltip)
This widget script is defined for the following widget types: GameTooltip
Chapter 29 Widget Reference 1273
OnTooltipSetSpell
Run when the tooltip is filled with information about a spell.
OnTooltipSetSpell(self)
See :SetSpell(),:SetSpellByID() and :GetSpell().
Arguments:
selfReference to the widget for which the script was run (gametooltip)
This widget script is defined for the following widget types: GameTooltip
OnTooltipSetUnit
Run when the tooltip is filled with information about a unit.
OnTooltipSetUnit(self)
See :SetUnit() and :GetUnit().
Arguments:
selfReference to the widget for which the script was run (gametooltip)
This widget script is defined for the following widget types: GameTooltip
OnUpdate
Run each time the screen is drawn by the game engine.
OnUpdate(self, elapsed)
This handler runs for each frame (not Frame) drawnif WoW is currently
running at 27.5 frames per second, the OnUpdate handlers for every visible
Frame,Animation and AnimationGroup (or descendant thereof) are run
approximately every 2/55ths of a second. Therefore, OnUpdate handler can be
useful for processes which need to be run very frequently or with accurate
timing, but extensive processing in an OnUpdate handler can slow down the
game’s framerate.
See the chapter ‘‘Responding to Graphic Updates with OnUpdate’’ for more
information.
Arguments:
selfReference to the widget for which the script was run (frame)
elapsedNumber of seconds since the OnUpdate handlers were last run (likely
a fraction of a second) (number)
This widget script is defined for the following widget types: Alpha, Animation,
AnimationGroup, Button, CheckButton, ColorSelect, Cooldown,
DressUpModel, EditBox, Frame, GameTooltip, MessageFrame, Minimap,
Model, MovieFrame, Path, PlayerModel, Rotation, Scale, ScrollFrame,
ScrollingMessageFrame, SimpleHTML, Slider, StatusBar, TabardModel,
Translation
OnUpdateModel
Run when a model changes or animates.
OnUpdateModel(self)
1274 Part IV Reference
Arguments:
selfReference to the widget for which the script was run (model)
This widget script is defined for the following widget types: DressUpModel,
Model, PlayerModel, TabardModel
OnValueChanged
Run when the slider’s or status bar’s value changes.
OnValueChanged(self, value)
Run when the value is set programmatically with Slider:SetValue() or
StatusBar:SetValue(), as well as when the value is set by the user dragging
the slider thumb.
Arguments:
selfReference to the widget for which the script was run (frame)
valueNew value of the slider or the status bar (number)
Example:
-- Use a slider to move a frame across the center of the screen
local button = CreateFrame(“Button“, “TestButton“, UIParent, i
“UIPanelButtonTemplate2“)
local slider = CreateFrame(“Slider“, “TestSlider“, UIParent, i
“OptionsSliderTemplate“)
slider:SetPoint(“CENTER“, 0, -60)
slider:SetWidth(400)
slider:SetMinMaxValues(-200, 200)
slider:SetValueStep(1)
slider:SetScript(“OnValueChanged“, function(self, value)
button:SetPoint(“CENTER“, value, 0)
end)
slider:SetValue(0)
This widget script is defined for the following widget types: Slider, StatusBar
OnVerticalScroll
Run when the scroll frame’s vertical scroll position changes.
OnVerticalScroll(self, offset)
Arguments:
selfReference to the widget for which the script was run (scrollframe)
offsetNew vertical scroll position (in pixels, measured from the topmost
scroll position) (number)
This widget script is defined for the following widget types: ScrollFrame
PostClick
Run immediately following the button’s OnClick handler with the same
arguments.
PostClick(self, “button“, down)
Useful for processing clicks on a button without interfering with handlers
inherited from a secure template. For further details, see the example under
OnClick.
Chapter 29 Widget Reference 1275
Arguments:
selfReference to the widget for which the script was run (button)
buttonName of the mouse button responsible for the click action (string)
downTrue for a mouse button down action; false for button up or other
actions (boolean)
This widget script is defined for the following widget types: Button,
CheckButton
PreClick
Run immediately before the button’s OnClick handler with the same
arguments.
PreClick(self, “button“, down)
Useful for processing clicks on a button without interfering with handlers
inherited from a secure template. For further details, see the example under
OnClick.
Arguments:
selfReference to the widget for which the script was run (button)
buttonName of the mouse button responsible for the click action (string)
downTrue for a mouse button down action; false for button up or other
actions (boolean)
Example:
<!--
Outside of combat, change the button’s spell based on the class you are
targeting.
-->
<PreClick>
if InCombatLockdown() then
return
end
local class = select(2, UnitClass(“target“))
local spell
if class == “WARRIOR“ then
spell = “Blessing of Kings“
elseif class == “ROGUE“ then
spell = “Blessing of Might“
else
spell = “Blessing of Wisdom“
end
self:SetAttribute(“spell“, spell)
</PreClick>
This widget script is defined for the following widget types: Button,
CheckButton
CHAPTER
30
Events Reference
To write an addon for World of Warcraft that can monitor changes in game
state, you must make use of game events. There are more than 400 differ-
ent events and while only a fraction of them will be used by any specific
addon, this chapter attempts to introduce each of the different events. In prac-
tice you should consult the online reference at http://wowprogramming.com/
docs/events for in-depth information about events (where available).
ACHIEVEMENT_EARNEDFires when the player earns an achievement
ACTIONBAR_HIDEGRIDFires when an item, spell or other entity that can be
placed into an action bar slot is removed from the cursor
ACTIONBAR_PAGE_CHANGEDFires when the main action bar changes pages
ACTIONBAR_SHOWGRIDFires when an item, spell or other entity that can be
placed into an action bar slot is picked up onto the cursor
ACTIONBAR_SLOT_CHANGEDFires when the contents of an action bar slot
change
ACTIONBAR_UPDATE_COOLDOWNFires when the cooldown for an action bar
item begins or ends
ACTIONBAR_UPDATE_STATEFires when the state of an action bar item
changes
ACTIONBAR_UPDATE_USABLEFires when an action becomes usable or
unusable
ACTIVE_TALENT_GROUP_CHANGEDFires when the player (with Dual Talent
Specialization enabled) switches talent builds
1277
1278 Part IV Reference
ADDON_ACTION_FORBIDDENFires when a non-Blizzard addon attempts to
use a protected API
ADDON_LOADEDFires when an addon and its saved variables are loaded
AREA_SPIRIT_HEALER_IN_RANGEFires when the player enters into the area
of effect of a spirit healer that periodically resurrects nearby player units
AREA_SPIRIT_HEALER_OUT_OF_RANGEFires when the player leaves the area
of effect of a spirit healer that periodically resurrects nearby player units
ARENA_OPPONENT_UPDATEFires when the availability of information about
an arena opponent changes
ARENA_TEAM_INVITE_REQUESTFires when the player is invited to join an
arena team
ARENA_TEAM_ROSTER_UPDATEFires when roster detail information for one
of the player’s arena teams becomes available
ARENA_TEAM_UPDATEFires when the player joins or leaves an arena team
AUCTION_BIDDER_LIST_UPDATEFires when information becomes available
or changes for the list of auctions bid on by the player
AUCTION_HOUSE_CLOSEDFires when the player ends interaction with an
auction house
AUCTION_HOUSE_SHOWFires when the player begins interaction with an
auction house
AUCTION_ITEM_LIST_UPDATEFires when the information becomes avail-
able for the list of auction browse/search results
AUCTION_OWNED_LIST_UPDATEFires when information becomes available
or changes for the list of auctions placed by the player
AUTOEQUIP_BIND_CONFIRMFires when the player attempts to equip an item
which will become soulbound in the process
AUTOFOLLOW_BEGINFires when the player starts following another
character
AUTOFOLLOW_ENDFires when the player stops following another character
BAG_UPDATEFires when the contents of one of the player’s containers
change
BAG_UPDATE_COOLDOWNFires when the cooldown begins or ends for an item
in one of the player’s containers
BANKFRAME_CLOSEDFires when the player ends interaction with a bank
BANKFRAME_OPENEDFires when the player begins interaction with a bank
Chapter 30 Events Reference 1279
BARBER_SHOP_APPEARANCE_APPLIEDFires after changes to the player’s
appearance have been purchased at a barber shop
BARBER_SHOP_CLOSEFires when the player ends interaction with a bar-
ber shop
BARBER_SHOP_OPENFires when the player begins interaction with a bar-
ber shop
BARBER_SHOP_SUCCESSFires immediately when changes to the player’s
appearance have been purchased at a barber shop
BATTLEFIELDS_CLOSEDFires when the UI is no longer available for queue-
ing for an arena or specific battleground instance
BATTLEFIELDS_SHOWFires when the UI becomes available for queueing for
an arena or specific battleground instance
BATTLEFIELD_MGR_EJECTEDFires when the player has been removed from
a queued world PvP zone (e.g. Wintergrasp)
BATTLEFIELD_MGR_EJECT_PENDINGFires when the player will be removed
from or cannot yet enter a queued world PvP zone (e.g. Wintergrasp)
BATTLEFIELD_MGR_ENTEREDFires when the player has been accepted into
a queued world PvP zone (e.g. Wintergrasp)
BATTLEFIELD_MGR_ENTRY_INVITEFires when the player is invited to enter
a queued world PvP zone (e.g. Wintergrasp)
BATTLEFIELD_MGR_QUEUE_INVITEFires when the player is invited to queue
for a world PvP zone (e.g. Wintergrasp)
BATTLEFIELD_MGR_QUEUE_REQUEST_RESPONSE—Fires in response to the
player’s attempt to enter or queue for a world PvP zone (e.g. Wintergrasp)
BATTLEFIELD_MGR_STATE_CHANGEFires when the player’s state changes in
the queue for a world PvP zone (e.g. Wintergrasp)
BILLING_NAG_DIALOGFires when a message should be shown about the
player’s paid game time expiring soon
BIND_ENCHANTFires when the player attempts to an enchant an item which
will become soulbound in the process
CALENDAR_ACTION_PENDINGFires when a change to the calendar is in
progress
CALENDAR_CLOSE_EVENTFires when the player ends viewing or editing
details of a calendar event
CALENDAR_EVENT_ALARMFires when a calendar event is soon to begin
CALENDAR_NEW_EVENTFires when an event created by the player is added
to the calendar
1280 Part IV Reference
CALENDAR_OPEN_EVENTFires when the player begins viewing or editing
details of a calendar event
CALENDAR_UPDATE_ERRORFires when a calendar-related error message
should be displayed
CALENDAR_UPDATE_EVENTFires when details become available for the event
being viewed or edited
CALENDAR_UPDATE_EVENT_LISTFires when the list of events visible on the
calendar changes
CALENDAR_UPDATE_INVITE_LISTFires when the invite/signup list is
updated for the event being viewed or edited
CALENDAR_UPDATE_PENDING_INVITESFires when the player receives new
calendar event invitations
CANCEL_LOOT_ROLLFires when the player cancels a loot roll
CANCEL_SUMMONFires when a summons offered to the player is canceled
CHANNEL_COUNT_UPDATEFires when the number of members in a world or
custom chat channel changes
CHANNEL_FLAGS_UPDATEDFires when information about a channel for the
channel list display changes
CHANNEL_INVITE_REQUESTFires when a player is invited into a chat channel
CHANNEL_PASSWORD_REQUESTFires when the player attempts to join a pass-
word protected channel
CHANNEL_ROSTER_UPDATEFires when the list of members in a channel
changes
CHANNEL_UI_UPDATEFires when information for the channel list display
changes
CHANNEL_VOICE_UPDATEFires when a member in a voice chat channel starts
or stops speaking
CHARACTER_POINTS_CHANGEDFires when the player’s amount of available
talent points changes
CHAT_MSG_ACHIEVEMENTFires when a nearby character earns an
achievement
CHAT_MSG_ADDONFires when an addon communication message is received
(see SendAddonMessage(), Chapter 27, ‘‘API Reference’’)
CHAT_MSG_AFKFires when an automatic AFK response is received
CHAT_MSG_BATTLEGROUNDFires when a message is received in the battle-
ground chat channel
Chapter 30 Events Reference 1281
CHAT_MSG_BATTLEGROUND_LEADERFires when a message is received in the
battleground chat channel from the battleground group leader
CHAT_MSG_BG_SYSTEM_ALLIANCEFires when an Alliance-related
battleground system message is received
CHAT_MSG_BG_SYSTEM_HORDEFires when a Horde-related battleground sys-
tem message is received
CHAT_MSG_BG_SYSTEM_NEUTRALFires when a general battleground, zone or
world message is received
CHAT_MSG_CHANNELFires when a message is received in a world or custom
chat channel
CHAT_MSG_CHANNEL_JOINFires when another character joins a world or
custom chat channel monitored by the player
CHAT_MSG_CHANNEL_LEAVEFires when another character leaves a world or
custom chat channel monitored by the player
CHAT_MSG_CHANNEL_LISTFires in response to a channel list query (e.g.
/chatlist)
CHAT_MSG_CHANNEL_NOTICEFires when certain actions happen on a world
or custom chat channel
CHAT_MSG_CHANNEL_NOTICE_USERFires when certain actions pertaining to
specific members happen on a world or custom chat channel
CHAT_MSG_COMBAT_FACTION_CHANGEFires when the player gains or loses
reputation with a faction
CHAT_MSG_COMBAT_HONOR_GAINFires when the player gains honor points
CHAT_MSG_COMBAT_MISC_INFOFires for miscellaneous messages to be dis-
played in the combat log, such as loss of equipment durability upon
death
CHAT_MSG_COMBAT_XP_GAINFires when the player gains experience points
CHAT_MSG_DNDFires when an automatic DND response is received
CHAT_MSG_EMOTEFires when a custom emote message is received
CHAT_MSG_FILTEREDFires when the player attempts to send a chat message
which is blocked by the spam filter
CHAT_MSG_GUILDFires when a message is received in the guild chat channel
CHAT_MSG_GUILD_ACHIEVEMENTFires when a member of the player’s guild
earns an achievement
CHAT_MSG_IGNOREDFires when an automatic response is received after
whispering or inviting a character who is ignoring the player
1282 Part IV Reference
CHAT_MSG_LOOTFires when receiving notice that the player or a member
of the player’s group has looted an item
CHAT_MSG_MONEYFires when the player receives money as loot
CHAT_MSG_MONSTER_EMOTEFires when a nearby NPC performs emote text
CHAT_MSG_MONSTER_PARTYFires when an NPC speaks to the player’s party
chat channel
CHAT_MSG_MONSTER_SAYFires when a nearby NPC speaks (visible only to
players in the immediate area)
CHAT_MSG_MONSTER_WHISPERFires when an NPC whispers to the player
CHAT_MSG_MONSTER_YELLFires when an NPC yells (visible to players in a
wide area or the entire zone)
CHAT_MSG_OFFICERFires when a message is received in officer chat
CHAT_MSG_OPENINGFires for messages about the player ‘‘opening’’ a world
object
CHAT_MSG_PARTYFires when a message is received in the party chat channel
CHAT_MSG_PET_INFOFires for pet-related messages normally displayed in
the combat log (e.g. summoning or dismissing a pet)
CHAT_MSG_RAIDFires when a message is received in the raid chat channel
CHAT_MSG_RAID_BOSS_EMOTEFires when a raid boss performs emote text
CHAT_MSG_RAID_BOSS_WHISPERFires when a raid boss whispers to the
player
CHAT_MSG_RAID_LEADERFires when a message is received in the raid chat
channel from the raid leader
CHAT_MSG_RAID_WARNINGFires when a raid warning message is received
CHAT_MSG_RESTRICTEDFires when the player attempts to send a chat
message which is disallowed because the player is on a trial account
CHAT_MSG_SAYFires when the player or a nearby character speaks (visible
to other nearby characters)
CHAT_MSG_SKILLFires when skill-related messages are received
CHAT_MSG_SYSTEMFires when a system message is received
CHAT_MSG_TEXT_EMOTEFires when the player receives a standard emote
(e.g. /dance,/flirt) message
CHAT_MSG_TRADESKILLSFires when the player or a nearby character per-
forms a trade skill recipe
CHAT_MSG_WHISPERFires when the player receives a whisper from a player
character
Chapter 30 Events Reference 1283
CHAT_MSG_WHISPER_INFORMFires when the player sends a whisper to a
player character
CHAT_MSG_YELLFires when the player or another player character yells
(visible to other characters in a wide area)
CINEMATIC_STARTFires when an in-game-engine cinematic begins to play
CINEMATIC_STOPFires when an in-game-engine cinematic stops playing
CLOSE_INBOX_ITEMFires when the mail message being viewed is no longer
available
CLOSE_TABARD_FRAMEFires when the player ends interaction with a tabard
designer
CLOSE_WORLD_MAPFireswhentheworldmapshouldbehiddeninresponse
to external conditions
COMBAT_LOG_EVENTFires when an event to be displayed in the combat log
is received
COMBAT_LOG_EVENT_UNFILTEREDFires when a combat log event is received
COMBAT_RATING_UPDATEFires when the player’s combat rating statistics
change
COMBAT_TEXT_UPDATEFires when a message is received which can be
displayed by the default UI’s floating combat text feature
COMPANION_LEARNEDFires when the player learns to summon a new mount
or non-combat pet
COMPANION_UPDATEFires when new information about the player’s mounts
and non-combat pets is available
CONFIRM_BINDERFires when the player attempts to set a new Hearthstone
location
CONFIRM_LOOT_ROLLFires when the player attempts to roll for a loot item
which Binds on Pickup
CONFIRM_SUMMONFires when a summons is offered to the player
CONFIRM_TALENT_WIPEFires when the player attempts to unlearn talents
CONFIRM_XP_LOSSFires when the player attempts to resurrect at a grave-
yard spirit healer
CORPSE_IN_INSTANCEFires when the player (dead, in spirit form)
approaches the entrance to the instance in which his corpse is located
CORPSE_IN_RANGEFires when the player (dead, in spirit form) approaches
near enough to his corpse to return to life
1284 Part IV Reference
CORPSE_OUT_OF_RANGEFires when the player (dead, in spirit form) moves
too far away from his corpse to resurrect
CRITERIA_UPDATEFires when information about achievement criteria or
player statistics becomes available
CURRENCY_DISPLAY_UPDATEFires when new information for the currency
list is available
CURRENT_SPELL_CAST_CHANGEDFires when the player starts or stops (can-
cels or finishes) casting a spell
CURSOR_UPDATEFires when the mouse cursor image or contents is changed
CVAR_UPDATEFires when the value of a configuration variable is updated
DELETE_ITEM_CONFIRMFires when the player attempts to delete an item
DISABLE_TAXI_BENCHMARKFires when a flight path benchmarking session
ends or is canceled
DISABLE_XP_GAINFires when the player disables experience point gains
DISPLAY_SIZE_CHANGEDFires when the screen resolution changes
DUEL_FINISHEDFires when a duel in which the player is participating ends
DUEL_INBOUNDSFires when the player reenters the duel area after leaving
its boundaries
DUEL_OUTOFBOUNDSFires when the player begins to move outside the
boundaries of a duel area
DUEL_REQUESTEDFires when the player is challenged to a duel
ENABLE_TAXI_BENCHMARKFires when taxi benchmarking mode is enabled
ENABLE_XP_GAINFires when the player re-enables experience point gain
after disabling it
END_BOUND_TRADEABLEFires when the player attempts an action which
will make a looted Bind on Pickup item no longer tradeable
END_REFUNDFires when the player attempts an action which will make an
item purchased with alternate currency no longer refundable
EQUIPMENT_SETS_CHANGEDFires when the player’s list of equipment sets
changes
EQUIPMENT_SWAP_FINISHEDFires when the process of switching equipment
sets is complete
EQUIPMENT_SWAP_PENDINGFires when the player begins to switch equip-
ment sets
EQUIP_BIND_CONFIRMFires when the player attempts to equip an item
which will become soulbound in the process
Chapter 30 Events Reference 1285
EXECUTE_CHAT_LINEFires when a chat message is encountered in a running
macro
FRIENDLIST_UPDATEFires when the content of the player’s friends list
becomes available or changes
GLYPH_ADDEDFires when a glyph is inscribed into the player’s spellbook
GLYPH_DISABLEDFires when a glyph slot is no longer available
GLYPH_ENABLEDFires when a glyph slot becomes available
GLYPH_REMOVEDFires when the player removes an inscribed glyph
GLYPH_UPDATEDFires when information about the player’s inscribed
glyphs becomes available
GMRESPONSE_RECEIVEDFires when the player receives a response to a GM
ticket
GMSURVEY_DISPLAYFires when the player is invited to participate in a GM
feedback survey
GM_PLAYER_INFOThis event is not yet documented
GOSSIP_CLOSEDFires when an NPC gossip interaction ends
GOSSIP_CONFIRMFires when the player is requested to confirm a gossip
choice
GOSSIP_CONFIRM_CANCELFires when an attempt to confirm a gossip choice
is canceled
GOSSIP_ENTER_CODEFires when the player attempts a gossip choice which
requires entering a code
GOSSIP_SHOWFires when an NPC gossip interaction begins
GUILDBANKBAGSLOTS_CHANGEDFires when information about the contents
of guild bank item slots changes or becomes available
GUILDBANKFRAME_CLOSEDFires when the player ends interaction with the
guild bank
GUILDBANKFRAME_OPENEDFires when the player begins interaction with the
guild bank
GUILDBANKLOG_UPDATEFires when information for the guild bank transac-
tion or money log becomes available
GUILDBANK_ITEM_LOCK_CHANGEDFires when an item in the guild bank is
locked for moving or unlocked afterward
GUILDBANK_TEXT_CHANGEDFires when the text associated with a guild bank
tab is changed
1286 Part IV Reference
GUILDBANK_UPDATE_MONEYFires when the amount of money in the guild
bank changes
GUILDBANK_UPDATE_TABSFires when information about guild bank tabs
becomes available
GUILDBANK_UPDATE_TEXTFires when text associated with a guild bank tab
becomes available
GUILDBANK_UPDATE_WITHDRAWMONEYFires when the amount of money the
player can withdraw from the guild bank changes
GUILDTABARD_UPDATEFires when the player’s guild tabard design changes
GUILD_EVENT_LOG_UPDATEFires when information for the guild event log
becomes available
GUILD_INVITE_CANCELFires when an invitation to join a guild is no longer
available
GUILD_INVITE_REQUESTFires when the player is invited to join a guild
GUILD_MOTDFires when the guild message of the day is updated
GUILD_REGISTRAR_CLOSEDFires when the player ends interaction with a
guild registrar
GUILD_REGISTRAR_SHOWFires when the player begins interaction with a
guild registrar
GUILD_ROSTER_UPDATEFires when new information about the contents of
the guild roster is available
HONOR_CURRENCY_UPDATEFires when the player’s amount of honor points
changes
IGNORELIST_UPDATEFires when the content of the player’s ignore list
becomes available or changes
IGR_BILLING_NAG_DIALOGFires when a message should be shown about
the player’s paid-per-hour game time expiring soon
INSPECT_ACHIEVEMENT_READYFires after the player attempts to compare
achievements with another character, indicating that achievement infor-
mation for the other unit has become available
INSPECT_HONOR_UPDATEFires when information about the inspected unit’s
PvP activities becomes available
INSPECT_TALENT_READYFires when information about the inspected
player’s talents becomes available
INSTANCE_BOOT_STARTFires when the player will soon be ejected from an
instance
Chapter 30 Events Reference 1287
INSTANCE_BOOT_STOPFires when the warning countdown for ejecting the
player from an instance is canceled
INSTANCE_LOCK_STARTFires when the player will soon be saved to an
instance
INSTANCE_LOCK_STOPFires when the warning countdown for saving the
player to an instance is canceled
ITEM_LOCKEDFires when an item in the player’s bags or equipped inven-
tory is locked for moving
ITEM_LOCK_CHANGEDFires when an item in the player’s bags or equipped
inventory is locked for moving or unlocked afterward
ITEM_PUSHFires when the player receives an item
ITEM_TEXT_BEGINFires when the player begins interaction with a readable
item or world object
ITEM_TEXT_CLOSEDFires when the player ends interaction with a readable
item or world object
ITEM_TEXT_READYFires when text changes or becomes available for the
readable item or world object with which the player is interacting
ITEM_TEXT_TRANSLATIONFires when a ‘‘translation’’ progress bar should
be displayed while the player interacts with a readable item or world
object
ITEM_UNLOCKEDFires when an item in the player’s bags or equipped
inventory is unlocked after moving
KNOWLEDGE_BASE_ARTICLE_LOAD_FAILUREFires when a knowledge base
article fails to load
KNOWLEDGE_BASE_ARTICLE_LOAD_SUCCESSFires when the contents of a suc-
cessfully loaded knowledge base article become available
KNOWLEDGE_BASE_QUERY_LOAD_FAILUREFires when a knowledge base
query fails
KNOWLEDGE_BASE_QUERY_LOAD_SUCCESSFires when results of a successful
knowledge base query become available
KNOWLEDGE_BASE_SERVER_MESSAGEFires when the knowledge base server
message changes or becomes available
KNOWLEDGE_BASE_SETUP_LOAD_FAILUREFires when the knowledge base’s
default listing fails to load
KNOWLEDGE_BASE_SETUP_LOAD_SUCCESSFires when the knowledge base’s
default listing becomes available
1288 Part IV Reference
KNOWLEDGE_BASE_SYSTEM_MOTD_UPDATEDFires when the knowledge base
system’s message of the day changes or becomes available
KNOWN_CURRENCY_TYPES_UPDATEFires when the currency list changes
KNOWN_TITLES_UPDATEFires when the number of titles available to the
player changes
LANGUAGE_LIST_CHANGEDFires when the list of known languages changes
LEARNED_SPELL_IN_TABFires when a spell is learned inside of a given spell
book tab
LEVEL_GRANT_PROPOSEDFires when the player is offered to instantly gain
a level thanks to a Recruit-A-Friend partner
LFG_MATCH_CANCELFires when an offered LFG group match is no longer
available
LFG_MATCH_REQUESTFires when the player has been matched to a group
via the LFG system and offered to join it
LFG_PENDING_CANCELFires when the LFG system is no longer attempting
to find a group for the player
LFG_PENDING_REQUESTFires when the LFG system is attempting to find a
group for the player
LFG_UPDATEFires when information about the player’s LFG system set-
tings changes or becomes available
LOCALPLAYER_PET_RENAMEDFires when the player’s pet is renamed
LOGOUT_CANCELFires when the logout countdown is aborted
LOOT_BIND_CONFIRMFires when the player attempts to loot a Bind on
Pickup item
LOOT_CLOSEDFires when the player ends interaction with a lootable corpse
or object
LOOT_OPENEDFires when the player begins interaction with a lootable
corpse or object
LOOT_SLOT_CLEAREDFires when the contents of a loot slot are removed
MACRO_ACTION_FORBIDDENFires when a macro script attempts to use a
protected API
MAIL_CLOSEDFires when the player ends interaction with a mailbox
MAIL_FAILEDFires when an outgoing mail message fails to send
MAIL_INBOX_UPDATEFires when information about the contents of the
player’s inbox changes or becomes available
Chapter 30 Events Reference 1289
MAIL_SEND_INFO_UPDATEFires when information about the outgoing mail
message’s attachments changes
MAIL_SEND_SUCCESSFires when an outgoing message is successfully sent
MAIL_SHOWFires when the player begins interaction with a mailbox
MEETINGSTONE_CHANGEDFires when new information is available for the
Looking For Group system
MERCHANT_CLOSEDFires when the player ends interaction with a vendor
MERCHANT_SHOWFires when the player begins interaction with a vendor
MERCHANT_UPDATEFires when information about a vendor’s available items
changes or becomes available
MINIGAME_UPDATE—Unused
MINIMAP_PINGFires when the player or a group member ‘‘pings’’ a point
on the minimap to share its location with the group
MINIMAP_UPDATE_TRACKINGFires when the player’s currently active track-
ing ability changes
MINIMAP_UPDATE_ZOOMFires when the minimap zoom type changes
MIRROR_TIMER_PAUSEFires when a special countdown timer is paused
MIRROR_TIMER_STARTFires when a special countdown timer starts
MIRROR_TIMER_STOPFires when a special countdown timer stops
MODIFIER_STATE_CHANGEDFires when a modifier key is pressed or released
MOVIE_COMPRESSING_PROGRESSFires when compression of a movie record-
ing starts
MOVIE_RECORDING_PROGRESSFires when movie recording starts
MOVIE_UNCOMPRESSED_MOVIEFires when the client prompts the player to
allow compression of a movie recording
MUTELIST_UPDATEFires when the content of the player’s muted list
becomes available or changes
NEW_AUCTION_UPDATEFires when the content of the auction house’s Create
Auction item slot changes
NEW_TITLE_EARNEDFires when the player earns a new title
NPC_PVPQUEUE_ANYWHEREFires when the player begins interaction with an
NPC which can queue the player for any battleground
OLD_TITLE_LOSTFires when one of the player’s titles is no longer available
OPEN_MASTER_LOOT_LISTFires when the list of master loot candidates
becomes available
1290 Part IV Reference
OPEN_TABARD_FRAMEFires when the player begins interaction with a tabard
designer
PARTY_CONVERTED_TO_RAIDFires when the player’s party becomes a raid
group
PARTY_INVITE_CANCELFires when a pending invitation to join a group is
no longer available
PARTY_INVITE_REQUESTFires when the player is invited to join a group
PARTY_LEADER_CHANGEDFires when information about the leadership of
the player’s party changes or becomes available
PARTY_LOOT_METHOD_CHANGEDFires when information about the loot rules
for the player’s party changes or becomes available
PARTY_MEMBERS_CHANGEDFires when information about the membership
of the player’s party changes or becomes available
PARTY_MEMBER_DISABLEFires when a party member goes offline
PARTY_MEMBER_ENABLEFires when an offline party member comes back
online
PETITION_CLOSEDFires when the player ends interaction with a guild or
arena team charter
PETITION_SHOWFires when a guild or arena team charter is presented to
the player
PETITION_VENDOR_CLOSEDFires when the player ends interaction with an
arena registrar
PETITION_VENDOR_SHOWFires when the player begins interaction with an
arena registrar
PETITION_VENDOR_UPDATEFires when information about available options
at an arena registrar becomes available
PET_ATTACK_STARTFires when the player’s pet starts auto-attacking
PET_ATTACK_STOPFires when the player’s pet stops auto-attacking
PET_BAR_HIDEFires when the pet action bar should be hidden
PET_BAR_HIDEGRIDFires when a pet ability is removed from the cursor
PET_BAR_SHOWGRIDFires when a pet ability is picked up onto the cursor
PET_BAR_UPDATEFires when information about the content of the pet action
bar changes or becomes available
PET_BAR_UPDATE_COOLDOWNFires when the cooldown begins or ends for
an ability on the pet action bar
PET_DISMISS_STARTFires when the player’s pet is dismissed
Chapter 30 Events Reference 1291
PET_FORCE_NAME_DECLENSIONFires when the player is prompted to pro-
vide Russian declensions for a pet’s name
PET_RENAMEABLEFires when the player is prompted to rename a pet which
has been renamed before
PET_STABLE_CLOSEDFires when the player ends interaction with the pet
stables
PET_STABLE_SHOWFires when the player begins interaction with the pet
stables
PET_STABLE_UPDATEFires when information about the pet stables’ content
changes or becomes available
PET_STABLE_UPDATE_PAPERDOLLFires when information about 3D models
used in the pet stables becomes available
PET_TALENT_UPDATEFires when the player’s pet talent information
changesthat is, when the pet is summoned, dismissed, gains or spends
talent points
PET_UI_CLOSEFires when information about the player’s pet is no longer
available
PET_UI_UPDATEFires when information about the player’s pet changes or
becomes available
PLAYERBANKBAGSLOTS_CHANGEDFires when the number of bank bag slots
purchased by the player changes
PLAYERBANKSLOTS_CHANGEDFires when the contents of a bank slot or bank
bag slot are changed
PLAYER_ALIVEFires when the player’s spirit is released after death or
when the player accepts a resurrection without releasing
PLAYER_AURAS_CHANGEDFires when the player gains or loses a buff or
debuff
PLAYER_CAMPINGFires when the player attempts to log out while not in a
major city, inn, or other ‘‘resting’’ area
PLAYER_CONTROL_GAINEDFires when the player regains control of his or
her character
PLAYER_CONTROL_LOSTFires when the player loses control of his or her
character
PLAYER_DAMAGE_DONE_MODSFires when an effect changes the player’s spell
bonus damage
PLAYER_DEADFires when the player dies
1292 Part IV Reference
PLAYER_ENTERING_BATTLEGROUNDFires when the player enters a battle-
ground instance
PLAYER_ENTERING_WORLDFired when the player enters the world, reloads
the UI, enters/leaves an instance or battleground, or respawns at a
graveyard. Also fires any other time the player sees a loading screen
PLAYER_ENTER_COMBATFires when the player begins melee auto-
attack mode
PLAYER_EQUIPMENT_CHANGEDFires when the player equips or unequips
an item
PLAYER_FARSIGHT_FOCUS_CHANGEDFires when the player’s viewpoint
changes
PLAYER_FLAGS_CHANGEDFires when a unit’s AFK or DND status changes
PLAYER_FOCUS_CHANGEDFires when the player’s focus unit changes
PLAYER_GAINS_VEHICLE_DATAFires when the player gains vehicle-related
attributes without necessarily entering a vehicle
PLAYER_GUILD_UPDATEFires when information about the player’s guild
membership changes
PLAYER_LEAVE_COMBATFires when the player stops melee auto-attack mode
PLAYER_LEAVING_WORLDFires when the player logs out or exits a world area
PLAYER_LEVEL_UPFires when the player gains a character level
PLAYER_LOGINFires immediately before PLAYER_ENTERING_WORLD on login
and UI reload
PLAYER_LOGOUTFires immediately before the player is logged out of
the game
PLAYER_LOSES_VEHICLE_DATAFires when the player loses vehicle-related
attributes without necessarily having been in a vehicle
PLAYER_MONEYFires when the player gains or spends money
PLAYER_PVP_KILLS_CHANGEDFires whenever a player’s number of Honor-
able Kills changes
PLAYER_QUITINGFires when the player attempts to exit WoW while not in
a major city, inn, or other ‘‘resting’’ area
PLAYER_REGEN_DISABLEDFires when the player enters combat status
PLAYER_REGEN_ENABLEDFires when the player leaves combat status
PLAYER_SKINNEDFires when another character takes the insignia from the
player’s corpse in a battleground or world PvP zone
PLAYER_TALENT_UPDATEFires when the player gains or spends talent points
Chapter 30 Events Reference 1293
PLAYER_TARGET_CHANGEDFires when the player changes targets
PLAYER_TOTEM_UPDATEFires when information about the player’s placed
totems changes or becomes available
PLAYER_TRADE_MONEYFires when the amount of money offered for trade
by the player changes
PLAYER_UNGHOSTFires when a player resurrects after being in spirit form
PLAYER_UPDATE_RESTINGFires when the player enters or leaves a major
city, inn or other ‘‘resting’’ area
PLAYER_XP_UPDATEFires when the player’s amount of accrued experience
points changes
PLAYTIME_CHANGEDFires when changes to the player’s limited play time
status take effect
PLAY_MOVIEFires when an in-game movie should be played
PREVIEW_PET_TALENT_POINTS_CHANGEDFires when pet talent points are
spent or unspent in preview mode
PREVIEW_TALENT_POINTS_CHANGEDFires when the player spends or
unspends talent points in preview mode
PVPQUEUE_ANYWHERE_SHOWFires when the player begins interacting with
the UI feature allowing battleground queueing from any location
PVPQUEUE_ANYWHERE_UPDATE_AVAILABLEFires when information for the
any-battleground queueing UI changes or becomes available
QUEST_ACCEPTEDFires when a new quest is added to the player’s quest log
(which is what happens after a player accepts a quest)
QUEST_ACCEPT_CONFIRMFires when certain kinds of quests (e.g. NPC escort
quests) are started by another member of the player’s group
QUEST_COMPLETEFires when the player is looking at the ‘‘Complete’’ page
for a quest, at a questgiver
QUEST_DETAILFires when details of an available quest are presented by a
questgiver
QUEST_FINISHEDFires when the player ends interaction with a questgiver
or ends a stage of the questgiver dialog
QUEST_GREETINGFires when a questgiver presents a greeting along with a
list of active or available quests
QUEST_ITEM_UPDATEFires when information about items in a questgiver
dialog is updated
1294 Part IV Reference
QUEST_LOG_UPDATEFires when the game client receives updates relating
to the player’s quest log (this event is not just related to the quests
inside it)
QUEST_PROGRESSFires when interacting with a questgiver about an active
quest
QUEST_WATCH_UPDATEFires when the player’s status regarding a quest’s
objectives changes, for instance picking up a required object or killing a
mob for that quest. All forms of (quest objective) progress changes will
trigger this event
RAID_INSTANCE_WELCOMEFires when the player enters an instance that has
a reset timer
RAID_ROSTER_UPDATEFires when the raid roster changes
RAID_TARGET_UPDATEFires when raid target icons are assigned or cleared
RAISED_AS_GHOULFires when the player is raised as a ghoul by a friendly
death knight
READY_CHECKFires when a ready check is triggered
READY_CHECK_CONFIRMFires when a unit responds to a ready check
READY_CHECK_FINISHEDFires when a ready check ends
REPLACE_ENCHANTFires when the player attempts to enchant an item which
is already enchanted
RESURRECT_REQUESTFires when another character offers to resurrect the
player
RUNE_POWER_UPDATEFires when the availability of one of the player’s rune
resources changes
RUNE_TYPE_UPDATEFires when the type of one of the player’s rune
resources changes
SCREENSHOT_FAILEDFires if an attempt to take a screenshot fails
SCREENSHOT_SUCCEEDEDFires when a screenshot is successfully taken
SEND_MAIL_COD_CHANGEDFires when the Cash On Delivery cost assigned
for the outgoing mail message changes
SEND_MAIL_MONEY_CHANGEDFires when the amount of money attached to
the outgoing mail message changes
SKILL_LINES_CHANGEDFires when the content of the player’s skill list
changes
SOCKET_INFO_CLOSEFires when the player ends interaction with the item
socketing UI
Chapter 30 Events Reference 1295
SOCKET_INFO_UPDATEFires when information about the contents of the
item socketing UI changes or becomes available
SOUND_DEVICE_UPDATEFires when information about sound input/output
devices changes or becomes available
SPELLS_CHANGEDFires when information about the contents of the player’s
spellbook changes or becomes available
SPELL_UPDATE_COOLDOWNFires when the cooldown on one of the player’s
spells begins or ends
SPELL_UPDATE_USABLEFires when a spell becomes usable or unusable
START_AUTOREPEAT_SPELLFires when the player casts a spell which auto-
matically repeats
START_LOOT_ROLLFires when an item becomes available for group loot
rolling
START_MINIGAME—Unused
STOP_AUTOREPEAT_SPELLFires when the player stops repetition of an auto-
matically repeating spell
SYNCHRONIZE_SETTINGSFires when game options are manually synchro-
nized with those saved on the server
TABARD_CANSAVE_CHANGEDFires when information about the player’s abil-
ity to save a guild tabard design changes or becomes available
TABARD_SAVE_PENDINGFires when the player attempts to save a guild
tabard design
TAXIMAP_CLOSEDFires when the player begins interaction with a flight
master
TAXIMAP_OPENEDFires when the player ends interaction with a flight
master
TIME_PLAYED_MSGFires when information about the player’s total time
played becomes available
TRACKED_ACHIEVEMENT_UPDATEFires when the player’s progress changes
on an achievement marked for watching in the objectives tracker
TRADE_ACCEPT_UPDATEFires when the player or trade target signals accep-
tance (or cancels acceptance) of the trade
TRADE_CLOSEDFires when a trade with another player ends or is canceled
TRADE_MONEY_CHANGEDFires when the amount of money offered by the
trade target changes
TRADE_PLAYER_ITEM_CHANGEDFires when the set of items offered for trade
by the player changes
1296 Part IV Reference
TRADE_POTENTIAL_BIND_ENCHANTThis event is not yet documented
TRADE_REPLACE_ENCHANTFires if the player attempts to enchant an item
offered by the trade target which is already enchanted
TRADE_REQUEST_CANCEL—Unused
TRADE_SHOWFires when a trade interaction with another character begins
TRADE_SKILL_CLOSEFires when the player ends interaction with a trade
skill recipe list
TRADE_SKILL_FILTER_UPDATEFires when the search filter for a trade skill
recipe list changes
TRADE_SKILL_SHOWFires when the player begins interaction with a trade
skill recipe list
TRADE_SKILL_UPDATEFires when information about the contents of a trade
skill recipe list changes or becomes available
TRADE_TARGET_ITEM_CHANGEDFires when the set of items offered for trade
by the target changes
TRADE_UPDATEFires when new information becomes available about a
trade process underway with another character
TRAINER_CLOSEDFires when the player ends interaction with a class or
skill trainer
TRAINER_DESCRIPTION_UPDATEFires when description information for the
selected trainer service changes or becomes available
TRAINER_SHOWFires when the player begins interaction with a class or skill
trainer
TRAINER_UPDATEFires when information about the contents of the trainer
service list changes or becomes available
TUTORIAL_TRIGGERFires when a contextual tutorial should be shown
UI_ERROR_MESSAGEFires when a game error message should be displayed
UI_INFO_MESSAGEFires when an informative message should be displayed
UNIT_ATTACKFires when a unit’s weapon (or standard melee attack dam-
age) changes
UNIT_ATTACK_POWERFires when a unit’s attack power changes
UNIT_ATTACK_SPEEDFires when a unit’s attack speed changes
UNIT_AURAFires when a unit loses or gains a buff or debuff.
UNIT_CLASSIFICATION_CHANGEDFires when a unit changes classification
(e.g. if an elite unit becomes non-elite)
Chapter 30 Events Reference 1297
UNIT_COMBATFires when a unit takes or recovers from damage due to a
combat effect
UNIT_COMBO_POINTSFires when a unit scores combo points on its target
UNIT_DAMAGEFires when a unit’s weapon damage changes
UNIT_DEFENSEFires when a unit’s defense changes
UNIT_DISPLAYPOWERFires when a unit’s primary power type (e.g. rage,
energy, mana) changes
UNIT_DYNAMIC_FLAGSFires when certain unit attributes change
UNIT_ENERGYFires when a unit’s energy level changes
UNIT_ENTERED_VEHICLEFires when a unit has entered a vehicle
UNIT_ENTERING_VEHICLEFires when a unit begins entering a vehicle
UNIT_EXITED_VEHICLEFires when a unit has exited a vehicle
UNIT_EXITING_VEHICLEFires when a unit begins exiting a vehicle
UNIT_FACTIONFires when a unit’s PvP status changes
UNIT_FLAGSFires when certain combat statuses for a unit change (e.g.
stunned, feared)
UNIT_FOCUSFires when a unit’s focus level changes
UNIT_HAPPINESSFires when the player’s pet’s happiness level changes
UNIT_HEALTHFires when a unit’s health level changes
UNIT_INVENTORY_CHANGEDFires when the player (or inspected unit) equips
or unequips items
UNIT_LEVELFires when a unit’s character level changes
UNIT_MANAFires when a unit’s mana level changes
UNIT_MAXENERGYFires when a unit’s maximum energy changes
UNIT_MAXFOCUSFires when a unit’s maximum focus changes
UNIT_MAXHAPPINESSFires when a unit’s maximum happiness changes
UNIT_MAXHEALTHFires when a unit’s maximum health changes
UNIT_MAXMANAFires when a unit’s maximum mana changes
UNIT_MAXRAGEFires when a unit’s maximum rage changes
UNIT_MAXRUNIC_POWERFires when a unit’s maximum runic power changes
UNIT_MODEL_CHANGEDFires when a unit’s 3D model changes (e.g. due to
shapeshifting, being polymorphed, or equipping gear)
UNIT_NAME_UPDATEFires when a unit’s name is changed
UNIT_PETFires when a unit gains or loses a pet
1298 Part IV Reference
UNIT_PET_EXPERIENCEFires when the player’s pet gains experience points
UNIT_PORTRAIT_UPDATEFires when a unit’s portrait changes (e.g. due to
shapeshifting, being polymorphed, or equipping gear)
UNIT_QUEST_LOG_CHANGEDFires when a unit’s quests change (accepted/
objective progress/abandoned/completed)
UNIT_RAGEFires when a unit’s rage level changes
UNIT_RANGEDDAMAGEFires when a unit’s ranged attack damage changes
UNIT_RANGED_ATTACK_POWERFires when a unit’s ranged attack power
changes
UNIT_RESISTANCESFires when a unit’s magic resistances change
UNIT_RUNIC_POWERFires when a unit’s runic power level changes
UNIT_SPELLCAST_CHANNEL_STARTFires when a unit starts channeling
aspell
UNIT_SPELLCAST_CHANNEL_STOPFires when a unit stops or cancels a chan-
neled spell
UNIT_SPELLCAST_CHANNEL_UPDATEFires when a unit’s channeled spell is
interrupted or delayed
UNIT_SPELLCAST_DELAYEDFires when a unit’s spell cast is delayed
UNIT_SPELLCAST_FAILEDFires when a unit’s spell cast fails
UNIT_SPELLCAST_FAILED_QUIETFires when a unit’s spell cast fails and no
error message should be displayed
UNIT_SPELLCAST_INTERRUPTEDFires when a unit’s spell cast is interrupted
UNIT_SPELLCAST_INTERRUPTIBLEFires when a unit’s spell cast becomes
interruptible again
UNIT_SPELLCAST_NOT_INTERRUPTIBLEFires when a unit’s spell cast
becomes uninterruptible
UNIT_SPELLCAST_SENTFires when a request to cast a spell (on behalf of the
player or a unit controlled by the player) is sent to the server
UNIT_SPELLCAST_STARTFires when a unit begins casting a spell
UNIT_SPELLCAST_STOPFires when a unit stops or cancels casting a spell
UNIT_SPELLCAST_SUCCEEDEDFires when a unit’s spell cast succeeds
UNIT_STATSFires when a unit’s primary attributes change
UNIT_TARGETFires when a unit’s target changes
UNIT_THREAT_LIST_UPDATEFires when a non-player unit’s threat list is
updated
Chapter 30 Events Reference 1299
UNIT_THREAT_SITUATION_UPDATEFires when a unit’s threat state changes
UPDATE_BATTLEFIELD_SCOREFires when information for the battleground
scoreboard changes or becomes available
UPDATE_BATTLEFIELD_STATUSFires when the player’s status in a battle-
ground or queue changes
UPDATE_BINDINGSFires when information about the player’s key binding
settings changes or becomes available
UPDATE_BONUS_ACTIONBARFires when information about the bonus action
bar changes or becomes available
UPDATE_CHAT_COLORFires when the color settings for chat message types
are updated
UPDATE_CHAT_COLOR_NAME_BY_CLASSFires when settings for per-class
color-coding of character names in chat are updated
UPDATE_CHAT_WINDOWSFires when saved chat window settings are loaded
UPDATE_EXHAUSTIONFires when the player’s rest state or amount of rested
XP changes
UPDATE_FACTIONFires when the contents of the reputation listing change
or become available
UPDATE_FLOATING_CHAT_WINDOWSFires when chat window layout should
be updated
UPDATE_GM_STATUSFires when the player’s GM ticket status (or ability to
submit tickets) changes
UPDATE_INSTANCE_INFOFires when information about instances to which
the player is saved changes or becomes available
UPDATE_INVENTORY_ALERTSFires when an equipped item’s durability alert
status changes
UPDATE_INVENTORY_DURABILITYFires when an equipped item’s durability
changes
UPDATE_LFG_LISTFires when results of a Looking for More query become
available
UPDATE_LFG_LIST_INCREMENTALFires when results of a Looking for More
query are updated
UPDATE_LFG_TYPESFires when information about possible Looking for
Group settings changes or becomes available
UPDATE_MACROSFires when information about the player’s macros changes
or becomes available
1300 Part IV Reference
UPDATE_MASTER_LOOT_LISTFires when the contents of the master loot
candidate list change or become available
UPDATE_MOUSEOVER_UNITFires when the mouse cursor moves over a visi-
ble unit
UPDATE_MULTI_CAST_ACTIONBARFires when the contents of the multi-cast
action bar change or become available
UPDATE_PENDING_MAILFires when information about newly received mail
messages (not yet seen at a mailbox) becomes available
UPDATE_SHAPESHIFT_COOLDOWNFires when the cooldown begins or ends
foranactiononthestance/shapeshiftbar
UPDATE_SHAPESHIFT_FORMFires when the player’s shapeshift form changes
UPDATE_SHAPESHIFT_FORMSFires when the contents of the stance/
shapeshift bar change or become available
UPDATE_SHAPESHIFT_USABLEFires when an ability on the stance/
shapeshift bar becomes usable or unusable
UPDATE_STEALTHFires when the player uses or cancels a stealth ability
UPDATE_TICKETFires when information about an active GM ticket changes
or becomes available
UPDATE_TRADESKILL_RECASTFires for each cast when performing multiple
casts of a trade skill recipe
UPDATE_WORLD_STATESFires when information for world state UI elements
changes or becomes available
USE_BIND_CONFIRMFires when the player attempts to use an item which
will become soulbound in the process
USE_GLYPHFires when the player begins to use a glyph
VARIABLES_LOADEDFires when non-addon-specific saved variables are
loaded
VEHICLE_ANGLE_SHOWFires when controls for vehicle weapon pitch should
be displayed
VEHICLE_ANGLE_UPDATEFires when the player’s vehicle weapon pitch
changes
VEHICLE_PASSENGERS_CHANGEDFires when the list of passengers in the
player’s vehicle changes
VEHICLE_POWER_SHOWFires when controls for vehicle weapon power
should be displayed
VEHICLE_UPDATEFires when information about the player’s vehicle
changes or becomes available
Chapter 30 Events Reference 1301
VOICE_CHANNEL_STATUS_UPDATEFires when voice-related status of a chat
channel changes
VOICE_CHAT_ENABLED_UPDATEFires when the client’s voice chat feature is
enabled or disabled
VOICE_LEFT_SESSIONFires when a voice-enabled member leaves a chat
channel
VOICE_PUSH_TO_TALK_STARTFires when the ‘‘Push to Talk’’ key binding is
activated
VOICE_PUSH_TO_TALK_STOPFires when the ‘‘Push to Talk’’ key binding is
deactivated
VOICE_SELF_MUTEFires when the player’s self mute setting changes
VOICE_SESSIONS_UPDATEFires when information about a voice chat ses-
sion changes or becomes available
VOICE_STARTFires when a channel member begins speaking in voice chat
VOICE_STATUS_UPDATEFires when a member of the player’s group changes
voice chat status
VOICE_STOPFires when a channel member finishes speaking in voice chat
WEAR_EQUIPMENT_SETFires when the player’s current equipment set
changes
WHO_LIST_UPDATEFires when results of a Who query become available
WORLD_MAP_NAME_UPDATEFires when the name of the current world map
area changes or becomes available
WORLD_MAP_UPDATEFires when the contents of the world map change or
become available
WORLD_STATE_UI_TIMER_UPDATEFires when the state of a timer world state
UI element changes or becomes available
WOW_MOUSE_NOT_FOUNDFires when a man-buttoned WoW mouse is not
found, in response to a DetectWowMouse() function call
ZONE_CHANGEDFires when the player moves between subzones or other
named areas
ZONE_CHANGED_INDOORSFires when the player moves between areas and
the ‘‘indoors/outdoors’’ status may have changed
ZONE_CHANGED_NEW_AREAFires when the player moves between major
zones or enters/exits an instance
Part
V
Appendixes
In This Part
Appendix A: Best Practices
Appendix B: Utilizing Addon Libraries
Appendix C: Tracking History Using Version Control Systems
Appendix D: Addon Author Resources
APPENDIX
A
Best Practices
Throughout this book the authors have made an effort to present code that fol-
lows patterns to make your programming life easier. However, not all of these
ideas can be passed on implicitly. This appendix presents generally accepted
practices that will empower you to be more effective at writing addons. These
tips will help you produce addons more quickly, write better-performing code,
and make your code itself more readable to others (and to yourself if you’re
away from a project for more than a few weeks).
Be aware that many people follow their own, more extensive sets of rules.
To some extent, ‘‘best practice’’ is as much a case of personal preference as it
is absolute commandments. We have done our best to pick the most widely
applicable, least controversial ideals for inclusion here. However, you should
always defer to your better judgment. If a solution presents itself that goes
against these ideas and you can’t think of an alternative or the alternatives are
cumbersome and awkward, by all means, use what works.
General Programming
Certain practices are applicable to nearly every programming language in
existence. These are not so much technical as they are conceptual; the intent
is to help you think about a problem in ways that make it easier to solve. If
you have had any formal training in programming, you will most likely be
familiar with the suggestions presented here.
1305
1306 Part V Appendixes
Use Meaningful Variable Names
If you’ve ever taken algebra or higher math, you know how difficult it can
be to swim in a sea of seemingly random letters and numbers. It takes
weeks of practice and memorization to fully understand and appreciate
the mish-mash of variables, coefficients, and operators necessary to describe
various constructs. This difficulty is no different and, in fact, is multiplied in
programming.
Often, a new programmer will use short, abbreviated variable names to
save time typing. At first the variables might seem self-evident, but that’s
only an illusionan illusion that quickly goes away. Take the following two
functions, for example:
function ic(i)
local a = 0
forj=0,4do
for k = 1, ns(j) do
local l = il(j, k)
if l and i == tn(sm(l, “item:(%d+):“)) then
a = a + sl(2, ii(j, k))
end
end
end
return a
end
function GetBagItemCount(itemID)
local count = 0
for bag = 0, 4 do
for slot = 1, GetContainerNumSlots(bag) do
local link = GetContainerItemLink(bag, slot)
if link and itemID == tonumber(strmatch(link, “item:(%d+):“)) then
count = count + select(2, GetContainerItemInfo(bag, slot))
end
end
end
return count
end
Someone unfamiliar with your code (including yourself after some time
awaywe cannot reiterate this enough) would have to spend an unfortunate
amount of time deciphering the first example. Even if you can follow the logic,
there is absolutely no indication of what it does on a conceptual level. The
only way to figure that out would be to research what the functions ns,il,
tn,sm,sl,andii do, all the while praying that they’re not implemented in
the same manner. You literally have to rename the identifiers in your mind to
understand their behavior.
Appendix A Best Practices 1307
On the other hand, the code in the second example clearly spells out exactly
what it does. The names of the functions it calls describe what they do, and
the returns are placed into variables that describe what they represent. Even
without looking at any of the code, the name of the function itself gives you
an idea of its behavior. The time you spend typing longer names at the front
end of development more than pays off in the long run.
It is possible to be concise and clear at the same time. Rather than typing out
the full description of something, you can use straightforward abbreviations.
For example, you can use desc instead of description,tbl instead of table,
numSlots instead of numberOfSlots,andsoon.
Variable Naming Exceptions
As with algebra, certain well-known, single-letter variables are used through-
out the software industry. Some of them, in fact, are borrowed directly from
mathematics. Table A-1 lists some of the more common terse variables and
their uses. If you decide to use these, make sure they are unique to the
contextthat is, the most important piece of data of its kind. For example, if
you use tasatimevalue,itshouldbetheonly(oratleastthemostimportant)
time value in the function. You can get a bit more flexibility by numbering
them (t1,t2) but it’s best to limit how far you take this.
Table A-1: Common Single-Letter Variables
VARIABLE USES
nA number or count of something.
tA time or table value.
r,g,b,aColor values. Red, green, blue, and alpha, respectively.
x,yScreen coordinates. Horizontal and vertical, respectively.
i,j*Numericalfor loop index: for i = 1, 10 do
k,v* Associative index and value in a for loop: for k, v in
pairs(someTable) do
_(underscore) Throwaway value. Something you don’t actually plan to use:
local var1, var2, _, _, var3 = someFunc()
In nested loops, it is usually better to use descriptive names to avoid confusion.
Use Named Constants Instead of Literals
Programs often require some arbitrary number to control their behavior. The
number of items that will fit in a list, a time limit for some complex operation,
and the default number of buttons on an action bar are all numbers that
could potentially be used in many places throughout your code. Rather than
1308 Part V Appendixes
hard coding these numbers each place they occur in your code, store them in
variables and use the variables in the code. These variables are treated like
constants you’d see in other languages.
By doing this, you only have to make one change to affect every location the
number appears in your code. The more occurrences of the number, the more
time (and potential for error) you save. As with meaningful variable names,
using constants gives significance to an otherwise random-looking number.
Convention dictates that you use all capital letters when naming your con-
stants (such as NUM_ACTIONBAR_BUTTONS). This makes them easily identifiable
in your source code, adding to readability. It is also a good idea to define all
related constants in one location, usually near the top of the file where they
are used or in the case of string constants, in a separate file for localization.
If they are scattered throughout your source code, you will needlessly waste
time searching for the one you want to change.
Be sure you don’t go overboard, though. If the number itself is fundamental
to the problem you are solving, go ahead and use it literally. For example, the
expression for calculating the circumference of a circle given its radius is 2πr.
If you need to make an area function, go ahead and use the 2 as-is (you’ll
obviously want to use a constant for the value of π,math.pi).
Organize for Easier Maintenance
Code can sometimes become unwieldy, especially as you revisit the code to
add features and fix bugs. Although you should make all efforts to organize
your code logically, it sometimes helps to go back and rework certain sections.
Rework Repetitive Code
You may be working on some bit of functionality and find yourself repeating
essentially the same lines of code over and over with only minor differences.
Consider creating a function that takes a few parameters and does all of the
steps that each repetitive part of your original code would do. This will save
you from many copy/paste errors as well as allow you to more easily add new
occurrences of the same sort of functionality.
Lua gives you even more of an edge with its tables. For more than a few
repetitions, it might make more sense to define all your parameters in a list
and then call the function in a for loop. For example, say you have a function,
MakeTexture, which takes three parameters: name,id,andfilename.Ifyou
have four textures, you could create a table and for loop like the following
(notice how the numerical index is used to generate an ID for the texture):
local textures = {
{ name = “Picture of me“,
file = “Interface\\AddOns\\MyMod\\Images\\me.tga“
},
Appendix A Best Practices 1309
{ name = “Picture of Ziggart“,
file = “Interface\\AddOns\\MyMod\\Images\\ziggart.tga“
},
{ name = “Frame Background“,
file = “Interface\\AddOns\\MyMod\\Images\\bg.tga“
},
{ name = “Some other texture“,
file = “Interface\\AddOns\\MyMod\\Images\\other.tga“
},
}
for id, entry in ipairs(textures) do
MyAddon.MakeTexture(entry.name, id, entry.file)
end
Now if you want to add a new texture, you can just create a new entry in
the table. If you insert one in the middle, the rest will automatically have the
correct IDs. Tables are also more recognizable as a data structure, so they make
more sense semantically than calling MakeTexture four times with the various
parameters.
Break Apart Long Functions
There is an upper limit to the number of words on a line of text or in a paragraph
before our brains have trouble absorbing the information. In a similar fashion,
functions that drag on and on over multiple screens become hard to follow.
If you have a really long function that does several different tasks, you might
want to break it apart into smaller functions that are called by one ‘‘master.’’
A fairly common rule of thumb is to keep functions down to one screen of
code or less.
Use Consistent Programming Style
Much of programming is a matter of personal style and preference. From
indentation format to variable names, you can make many choices that affect
the overall look and feel of your code. By remaining consistent in these choices,
you will serve yourself in the long run. Following are some examples of choices
you will have to make for yourself. Obviously, we could never hope to create
a complete list, but this provides a good sample to get you thinking.
Naming conventionsDo you begin all your functions with capital
or lowercase letters? Do you differentiate words with underscores or
‘‘camel case’’ (num_slots vs. numSlots)? Do all functions follow a specific
grammar (Verb,VerbNoun,andsoon)?
WhitespaceHow many blank lines do you have between functions?
Do you use tabs or spaces for indenting? How wide should indents be?
Do you split long statements into multiple lines?
1310 Part V Appendixes
OrganizationDo you split your source into multiple files by function-
ality? Are your functions mostly local or do you use a namespace table?
If you’re using a table, do you use method syntax or simple indexing
(MyMod:function vs. MyMod.function)?
Comment formatDo all of your functions have descriptions of their
parameters and effects? Do you include a copyright notice at the beginning
of your files? Do you use inline comments to describe complex algorithms?
Lua Tips
The simplicity of the Lua language can be deceptive. On the surface it displays
a clean, consistent syntax with intuitive keywords, and it has enough in
common with other languages that experienced programmers can get the
hang of it quite easily. However, to use Lua to its fullest extent takes a bit
of creative thinking. Many of its features are unique (or at least rare) and
certain idioms are downright foreign to programmers from other languages
(let alone people new to programming in general). To help you in this regard,
this section presents some tips that apply to Lua in general: some idiomatic
concepts that will help you take full advantage of its features, and various
optimizations to help you tune the performance of your addons.
Use Local Variables
As you may remember from Part I, variables are always global unless defined
with the local keyword. Global variables, while suitable for many purposes,
have a couple of important caveats. Each time you reference a global variable,
Lua has to do a table lookup on the global environment (_G) with the name
of said variable. Locals, on the other hand, are stored in a location of memory
determined when the code is compiled. In fact, their names are both irrelevant
and inaccessible during runtime.
Additionally, each global variable has the potential for conflict. If you name a
function something simple, like clear,orprocess, you may end up conflicting
with another addon that does the same. Some addons used to provide a global
print function, and because each one treated its arguments uniquely, there
often were real-world conflicts. And they all suffered the now-realized possi-
bility that WoW itself would one day include a function with the same name.
Oneobvioussolutionwouldbetogivethefunctionamoreuniquename,
perhaps tacking your addon name to the beginning, but that would unnec-
essarily add to your typing requirements. It would also add information to
your code that provides no meaningful advantage in understanding the logic,
potentially making it harder to follow.
For these reasons, you should use locals for every variable or function that
does not need to be referenced outside of a given scope (whether it’s the file,
Appendix A Best Practices 1311
a function, or even within an if block). Also, if you have a legitimate global
variable but performance is an issue, create a local copy. For example, if your
addon needs to use string.find several times per frame, add the following
line to the beginning (you can name it anything you want, perhaps strfind):
local string_find = string.find
Notice that this doesn’t call string.find (as shown by the lack of paren-
theses), but merely copies the function reference to the new local variable. By
using string_find throughout the file, you will save two table lookups on
each call (_G string find). These savings can add up quite quickly for
addons that do a lot of data processing each frame.
There is a practical limit to how many local variables a function can hold
reference to, but you aren’t likely to encounter it in your addon development.
Remember that there is a trade-off between making portions (such as constants)
available, and making them local for performance. Ensure you understand
your own code, and choose whatever makes the most sense.
Minimize Unnecessary Garbage
Lua is a garbage-collected language. Every so often, it will go through all the
objects in its memory and remove anything that is no longer being referenced.
Say you have a function that creates a local table when it runs. After that
function exits there are no references to that table, so it its memory will be
reclaimed later.
The Lua runtime is very fast by virtual machine standards. It outperforms
many other common scripting languages in various tasks. However, nothing in
the world is freeespecially in computing. Every time you call your function,
it creates a new table. Depending on how much information you pack into it,
how often you call the function, and a few other factors, collecting this garbage
can make a noticeable dent in WoW’s performance.
The three main garbage-collected objects that you will encounter are tables,
strings, and closures. Tables are definitely the most frequently abused objects.
Stringsarelessobviousbutcanbejustastroublesome.Eachuniquestringis
a collectable object. Once there are no more variables set to a particular string,
that string can be collected. Finally, each time you create a new function it
makes a closure that includes the function itself and references to any upvalues.
Just like waste in real life, you should make an effort to reduce, reuse, and
recycle. This will help prevent the garbage collection cycle from getting out
of hand.
However, don’t go overboard trying to wipe out every trace of garbage
creation from your addon. The garbage collector is there for a reason. If
you have a situation where you only need to create a new table, string, or
closure sporadically, go ahead. Simplicity should take priority over efficiency,
1312 Part V Appendixes
especially when you’re first designing your addon. If you notice a performance
bottleneck, then it’s time to investigate further optimizations.
It should also be noted that some of these techniques may actually take
longer to run than the avoided garbage collection operation. Unfortunately,
there is no sure way to know if this will be the case. It depends entirely on
how much data is being used and what kind of processing is going on. If you
start out using one technique and find that some areas need optimization, try
it the other way.
How to Reduce Garbage
The most obvious way to improve your addon’s garbage situation is not to
create any in the first place.
Use Multiple Returns and Variable Arguments Instead of Tables
When you need to return multiple values, or accept multiple arguments,
you may be tempted to simply wrap them in tables. If you come to Lua
from another programming language, you are probably used to dealing with
structures, arrays, and such when you want to operate on a set of data.
Sometimes, however, tables are unnecessary and even wasteful.
If a function needs to return a set of data, it may be best to return multiple
values unless the fundamental purpose of the function is to return some sort
of table. This way, the calling function has complete control over how to treat
the data. It can pack the returns into a table for later use, pass them to another
function for further processing, or simply store them in local variables as
needed.
You have seen plenty of examples of multiple returns thanks to their
extensive use in WoW’s API. However, most of those functions return a fixed
number of values. To return an arbitrary amount of data to a calling function,
you must use some form of recursion, which is explored a little later in this
appendix.
Receiving arguments, both fixed and variable, have been covered fairly
extensively in this book. The next section shows a way to operate on every
value passed through the vararg (...) and return the modified values without
using any intermediary tables.
Avoid Creating Unnecessary Strings
Try to steer clear of building strings piece by piece, adding new elements one
by one. If possible, store each element in a variable and then put them all
together in one mass concatenation. For example, say you are building a string
such as “123g 45s 67c“. You may be tempted to break it down as follows:
money = gold..“g “
money = money..silver..“s
money = money..copper..“c“
Appendix A Best Practices 1313
In this example, each line creates an entirely new string. Once the third line
executes, the first two strings that were created are now garbage and can be
collected. You can prevent this by building the entire string in one statement.
Each of the following lines achieves the same result:
money = gold..“g “..silver..“s “..copper..“c“
money = strconcat(gold, “g “, silver, “s “, copper, “c“)
money = string.format(“%dg %ds %dc“, gold, silver, copper)
In each case, only one string results from the operation, reducing the amount
of garbage. The third line actually has a slight advantage over the other two.
This means that the original example actually contains five entirely wasted
strings. In the string.format example, though, there’s only one: “%dg %ds
%dc“.
NOTE The function strconcat is actually specific to WoW. However, its
behavior is fundamental enough that it is appropriate for this section. It is simply a
function version of the concatenation operator (..). strconcat’s main advantage
over .. is that it can take a variable number of items to concatenatesomething
you will see in the next example.
This function is very similar to the table.concat() function provided in the Lua
standard libraries, only it doesn’t require the use of a table.
SETFORMATTEDTEXT
Another WoW-specific tip that belongs here is the use of SetFormattedText.
Suppose you intend to do something like the following after the code in the
Money example:
text:SetText(money)
In this case, you can reduce created garbage further still and get a slight per-
formance improvement by combining the string.format example and the
SetFormattedText function.
text:SetFormattedText(“%dg %ds %dc“, gold, silver, copper)
The only garbage you create now is the formatting string. The
SetFormattedText method does not generate the final string in the
Lua environment at all. It exists entirely in the UI engine.
There are also some situations where a more garbage-friendly solution is not
immediately apparent. Building a string in a loop, for instance, does not lend
1314 Part V Appendixes
itself to the preceding approach. Consider the following loop (and forgive the
contrived example):
local sequence = ““
for i = 1, 10 do
sequence = sequence..i
end
The price you pay for its simplicity is that every single time through the
loop it creates a brand new string. In addition to creating garbage, the Lua
interpreter must copy the existing string data each time through, which also
takes extra CPU time. One apparent solution to the garbage string problem is to
use a table to store each new addition to the string and then call table.concat.
But that still creates a garbage string for each element as well as generating an
extraneous table.
Luckily, there’s another trick using variable arguments and multiple returns.
This time you add recursion to the mix:
local function MakeSequence(n, ...)
if n > 1 then
return MakeSequence(n - 1, n, ...)
else
return n, ...
end
end
local sequence = strconcat(MakeSequence(10))
If you haven’t had much experience with recursive functions, it may be
hard to understand how this works. Let’s run through the execution of
MakeSequence.
1. MakeSequence is called with a single argument of 10.
2. Because nis more than 1,youcallMakeSequence with the arguments 9
(n-1)and10 (n). ... is empty so nothing else is passed this time around.
3. You are now one level deeper in recursion. nis 9and ... contains one
argument, 10. Again, because nis more than 1,youcallMakeSequence
with the arguments 8(n-1), 9(n), and 10 (...).
4. Recursion continues in this manner until the arguments to MakeSequence
are n:1and ...:2,3,4,5,6,7,8,9,10.
5. nhas finally reached 1, so you return the entire sequence from 1 to 10.
This is passed back down through each level of recursion until it reaches
the original call.
Appendix A Best Practices 1315
Ortoputitmoreconcisely:
MakeSequence(10)
MakeSequence(9, 10)
[Repetitive lines omitted]
MakeSequence(2, 3, 4, 5, 6, 7, 8, 9, 10)
MakeSequence(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
[Repetitive lines omitted]
return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
OncethefinalcalltoMakeSequence returns, the values are passed to
strconcat, which joins them all together as in the earlier money example.
In this way, you take advantage of Lua’s stack to store each step of the process.
Because items on the stack cease to exist as soon as the function ends, none of
the data you pass back and forth needs to be garbage-collected.
As with all of these suggestions, you must carefully consider the structure
and readability of your code. In addition, function calls themselves aren’t
completely free. In many cases you should seriously consider using a work
table, and the table.concat() function.
TAIL CALLS
You may have noticed that all the returns in the previous diagram are
identical. In reality, Lua processes the recursive function a bit differently than
presented. Take a look at the line where you call MakeSequence inside itself.
Because you are simply returning the results to the previous level without
making any modifications, Lua uses a technique called a tail call.
Normally, when you call a function, the parameters are pushed onto the
stack along with the location in your program where the function should
return. Then control is passed to the function being called. When that function
finishes, it returns to the location you pushed originally.
In a tail call situation, on the other hand, the same return location is used
for every level of recursion. When any level of MakeSequence returns, it goes
to the location of the very first call. Here is a more realistic diagram to illus-
trate what’s actually going on:
MakeSequence(10)
MakeSequence(9, 10)
[Repetitive lines omitted]
MakeSequence(2, 3, 4, 5, 6, 7, 8, 9, 10)
MakeSequence(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
return 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
(continued)
1316 Part V Appendixes
TAIL CALLS (continued)
To reiterate, tail calls are used only when you do not do anything to the
values being returned by the function you call. That means you must use a
return statement in conjunction with the call. Even if the function you are
calling does not return any values, as in the following example, Lua has no
way to know this for certain at compile time.
function foo()
-- Do stuff without returning anything
end
function bar()
foo()
end
When bar calls foo, there is a hidden operation of discarding any values
returned by foo, which breaks your chance to use tail recursion. Changing the
line inside bar to the following is all you need to fix it:
return foo()
Tail call recursion uses the function call stack more efficiently, since it
replaces the current function call with the new tail call, rather than simply
adding it on top. Think of each new function call as adding a layer on a
cake. To get back to your original location, you would need to remove all of
the layers you have added. Tail recursion helps the programming language
optimize by replacing the current level with a new one, instead of adding to
the stack.
Obviously, each unique problem requires slightly different logic. Let’s look
at another example to help you think recursively.
Many addons define a custom print function to make text output simpler
and to differentiate the addon’s output from a normal print,ortodirectthe
output to something other than the chat window. Most first attempts look
something like the following (notice the similarity to the original sequence
example):
local function print(...)
local output = ““
local n = select(“#“, ...)
fori=1,ndo
output = output..tostring(select(i, ...))
if i < n then
output = output..“, “
end
end
DEFAULT_CHAT_FRAME:AddMessage(“MyAddon: “..output)
end
Appendix A Best Practices 1317
In this function you have two main problems to solve:
1. Each parameter must be converted into a string because concatenation
does not automatically convert anything but numbers to strings.
2. The various parameters must be joined together with commas in between
each entry.
You can handle the first problem with a dedicated function to convert all its
parameters to strings and return the lot of them:
local function toManyStrings(...)
if select(“#“, ...) > 0 then
return tostring((...)), toManyStrings(select(2, ...))
end
end
When toManyStrings is called with more than one argument, it returns its
first argument converted to a string plus the toManyStringsed versions of the
rest of its arguments. Again, because you are not modifying the results of the
inner call to toManyStrings, Lua will use a tail call so you don’t have to worry
about the number of arguments.
The second problem has already been solved for you. WoW comes with
a function called strjoin that works a bit like strconcat, taking a variable
number of arguments and putting them together. However, the first parameter
to strjoin is a separator that is placed in between each element of the concate-
nation. For example, strjoin(“ sep “, “hello“, “middle“, “goodbye“)
returns the string “hello sep middle sep goodbye“. Putting these two solu-
tions together, your print function now becomes much simpler and produces
far less garbage:
local function print(...)
DEFAULT_CHAT_FRAME:AddMessage(“MyAddon: “..strjoin(“, “, toManyStrings(...)))
end
Recyclable Objects
Recycling objects is easy to do, but the need and manner to do so may not be
immediately apparent. Consider the following function, which hides a number
of predefined frames:
local function HideFrames()
local frames = {
PlayerFrame,
TargetFrame,
MinimapCluster,
}
for _, frame in ipairs(frames) do
frame:Hide()
end
end
1318 Part V Appendixes
Each time you call this function it re-creates the frames table. After the
function exits, frames goes out of scope and becomes collectable. The solution
is simply to move the table to the same scope as the HideFrames function
itself:
local frames = {
PlayerFrame,
TargetFrame,
MinimapCluster,
}
local function HideFrames()
for _, frame in ipairs(frames) do
frame:Hide()
end
end
The reference to the table will now persist as long as the scope it shares with
HideFrames exists.
There is a tradeoff made using this technique. By defining the frames table at
the file level, the memory is consumed at load time. With the previous listing,
we defer creation of the table until it’s actually needed. However, this tradeoff
is easily dismissed in nearly every situation. Once the memory is allocated, it is
completely free. Without garbage collection to worry about, it uses absolutely
no processor time to remain in existence. Furthermore, HideFrames operates
more quickly because the original version has to go through the process of
creating the table each time.
In the same way, you should not be creating functions inside other
functionsfunction() end is to functions what {}is to tablesunless
you have a specific need for a new closure.
Recycle Tables
Tables are the only mutable garbage-collected objects in Lua. Unlike strings
and functions, you can directly manipulate the contents of tables. This unique
characteristic allows you to empty individual tables and reuse them.
There are a few ways to accomplish table recycling. In fact, some addon
authors have created libraries for just this purpose. The simplest method
uses a table to store the empty tables, a function to get an empty table,
and another function to recycle an unneeded table. Following is one possible
implementation:
local freeTables = {}
function GetTable()
return table.remove(freeTables) or {}
end
Appendix A Best Practices 1319
function RecycleTable(t)
for key in pairs(t) do
t[key] = nil
end
table.insert(freeTables, t)
end
Whenever you want a new table, you call GetTable. This function attempts
to remove a recycled table from freeTables. A new one will be created for you
if freeTables is empty. Once you’re done with the table, you call RecycleTable
to empty it and place it back into freeTables.
The major disadvantage of table recycling is that it puts you, the pro-
grammer, back in charge of handling memory allocation and de-allocation,
essentially taking on the role of garbage collector. In fact, some programmers
believe this completely defeats the purpose of using a garbage-collected lan-
guage in the first place. However, in time-critical tasks where you need to use
(and discard) many small tables, the performance gains cannot be ignored.
It is up to you to strike the appropriate balance between performance and
clarity.
Other Fine-tuning Optimizations
The next few tips offer slight performance improvements for various situations.
For the most part, Lua is fast enough to let you organize your addon’s logic
as intuitively as possible. However, there may be times when you need to
squeeze out every last ounce of CPU power.
Check Expected Conditions First
When Lua processes a chain of if ... elseif statements, it goes through one
by one until it finds a condition that evaluates to trueor it runs into the
end. If the chain is long enough and executed frequently, careful ordering can
provide a substantial speed improvement. Most of the time when creating such
statements, you will have some idea of which conditions are most likely. Take
advantage of this foreknowledge to place the most likely conditions earlier in
the chain, as in the following pseudo-code:
if likely condition then
do stuff
elseif less likely condition then
do other stuff
elseif equally likely condition then
do yet some more stuff
elseif unlikely condition then
more stuff goes here
end
1320 Part V Appendixes
Even if you do not know beforehand what conditions will be most likely,
some simple profiling tests can help figure that out for you. For instance,
you could maintain counters for each clause that increment whenever they
execute. Then you could create a function to print out the stats. Most of the
time, such optimization is unnecessary. If you’re doing anything in OnUpdate
or some other extremely frequent code path, though, it may just be worth the
research. (Remember to remove said counters for the release version of your
mod because incrementing them has its own performance impact.)
Exploit Shortcut Evaluation
In a similar vein, you can use a feature of Lua (and other programming
languages) called shortcut evaluation to optimize the conditionals themselves.
Consider the expression aorb.Theor operator evaluates to true if either
aor bevaluates to true. Once Lua knows that ais true, there is no reason to
evaluate b. Similarly, as soon as it’s known that cis false in the expression
c and d, the entire expression is known to be false.
This also has the interesting benefit (in Lua) that every non-nil, non-false
value is considered true. Then you can initialize in the following way:
variable = variable or “Some default string“
to accomplish something equivalent to the following:
if not variable then
variable = “Some default string“
end
Depending on your specific need, you may find the Boolean expression
easier to read.
In addition, any time you have a complex condition with several clauses,
you should try to put the most likely and/or fastest-to-evaluate clauses first.
In pseudo-code, this would look something like the following:
if likely condition or less likely condition then
do stuff
elseif fast condition and slow condition then
do stuff
end
NOTE This section describes the logical result of the evaluation of Boolean
expressions. As discussed in Chapter 2, the actual results of the and and or
operators are one of the two operands depending on whether the first one is
interpreted as true (anything other than false or nil)—the
return table.remove(freeTables) or {} statement from the earlier
GetTable function, for example.
Appendix A Best Practices 1321
Use Tables as a Logic Structure
Sometimes you will have a long chain of if ... elseif where each clause
compares the same variable to some constant. The prime example in addon
programming is an OnEvent script. Consider the following:
if event == “SOME_EVENT“ then
-- do stuff
elseif event == “ANOTHER_EVENT“ then
-- do stuff
elseif event == “THIRD_EVENT“ then
-- do stuff
elseif event == “FOURTH_EVENT“ then
-- do stuff
end
You can use a table in a manner similar to the ‘‘Rework Repetitive Code’’
section earlier in this appendix. Instead of the if statement, you fill a table
with functions indexed by the name of the event:
local eventHandlers = {
[“SOME_EVENT“] = function(frame, namedArgument)
-- do stuff
end,
[“ANOTHER_EVENT“] = function(frame, namedArgument1, namedArgument2)
-- do stuff
end,
[“THIRD_EVENT“] = function(frame)
-- do stuff
end,
[“FOURTH_EVENT“] = function()
-- do stuff
end
}
Now the OnEvent script can be simplified to four lines (or one if you are
careful about what events you register):
function MyEventHandler(frame, event, ...)
local handler = eventHandlers[event]
if handler then
handler(frame, ...)
end
end
This technique affords a few advantages:
The underlying architecture of the table lookup usually executes more
quickly than a string of if ... elseif clauses, especially with a large
number of entries.
1322 Part V Appendixes
Each event handler is a separate entity. Defining separate functions for
each one adds a level of context that can make the code easier to follow.
Parameters can be adjusted to suit the event. As demonstrated in the
preceding example, you can give names to the individual elements of
... that would normally be accessed via select or by creating new local
variables in each if/elseif clause. You can even eliminate parameters
altogether if they are irrelevant to the given event.
As with the textures example earlier, you can use the table keys for the
actual registering and unregistering of the events:
for event in pairs(eventHandlers) do
someFrame:RegisterEvent(event)
end
Cache Frequently Accessed Values
There are many situations where you use a function to generate or retrieve a
value based solely on a given parameter. For instance, the slash command han-
dling system scans through the SlashCmdList table’s indexes, and then looks
for corresponding global variables. If the variable matches the slash command
you used, WoW executes the associated function from SlashCmdList.
With the potential for dozens of unique functions each with several equiva-
lent slash commands (for example, /t,/w,/tell,and/whisper), the amount
of processing necessary to select the appropriate function is substantial (take
a look at ChatEdit_ParseText in FrameXML\ChatFrame.lua to see what we
mean). WoW solves this problem by storing the results of each unique com-
mand search in a table called hash_SlashCmdList.Whenyouuseaslash
command, it first looks to see if it’s in the list. If so, it immediately uses the
associated function. Otherwise, it goes through the more involved process.
You can create an easy-to-use caching system with a simple metatable trick.
From the point of view of the code using the cache, it behaves as a simple
table. For example:
print(cacheTable[entry])
You make cacheTable into a cache with code like the following:
cacheTable = setmetatable({}, {
__index = function (table, parameter)
local value = DoStuff(parameter)
rawset(table, parameter, value)
return value
end
})
Now whenever you provide an entry that doesn’t exist, a new entry will be
created with the result of DoStuff(parameter).
Appendix A Best Practices 1323
The WoW Environment
The last part of this appendix deals specifically with constructs and procedures
unique to World of Warcraft.
Use What You’re Given
By now, it should be second nature to look for APIs and widget methods to
help with your day-to-day tasks. However, many other built-in features go
neglected. For instance, authors often write their own functions to convert the
returns from UnitName into nameor name-realmto indicate cross-realm
players. Granted, this is a rather trivial task, but WoW already provides such
a function called GetUnitName at the end of FrameXML\UnitFrame.lua.
Obviously, we do not expect you to familiarize yourself with the entirety
of FrameXML code as you’re starting out, but it is always a good idea to
look in files that may be related to your addon, both to see how things are
done in the default UI and to find functions to take advantage of yourself. For
example, if you are writing an alternative quest frame, you should look over
QuestFrame.lua and QuestFrame.xml before you begin work on your addon.
GetBagItemCount from the beginning of this appendix could actually be
improved slightly. Rather than forbag=0,4do,where4is a prime
example of a magic number, you can define a constant for the number
of bags. However, Blizzard has saved you the trouble. Near the top of
FrameXML\ContainerFrame.lua is the constant NUM_BAG_FRAMES,whichrepre-
sents the number of bags besides the backpack. Using the Blizzard-defined
constant adds a bit of future-proofing to your code. If they ever increase the
number of bags a player can carry, they will bump NUM_BAG_FRAMES to the new
count and your function will be instantly compatible.
Localize with Global Strings
Virtually every display string in the UI is stored in a constant in FrameXML\
GlobalStrings.lua. This file is translated to every language WoW supports.
By using the constants in this file for various aspects of your addon, you will
be automatically localizing certain parts of it, which is of great benefit to your
international users.
Error messages, button text, combat log strings, and many others are there
for the taking. Many common terms such as ‘‘Yes,’’ ‘‘No,’’ and ‘‘Okay,’’ are easy
enough to recognize. You will also see strings for the various races, genders,
classes, and other commonly used terms. Whenever you are looking into
localization for your addon, open GlobalStrings.lua and do a preliminary
search for the terms you want.
Even if you do not see the exact phrase you’re looking for, the search may still
help. If you are trying to do localization yourself, you may be able to figure out
1324 Part V Appendixes
the basic structure of the phrase in the target language but not how some par-
ticular term translates. You can find GlobalStrings.lua from other locales on
some addon sites and compare the phrases to come up with the missing term.
Avoid Deprecated Systems
The World of Warcraft UI code has gone through many evolutionary and
revolutionary changes as new needs for the game and from the addon com-
munity have come to light. New systems are constantly being added and
tweaked to take better advantage of Lua design patterns, improve efficiency,
and implement new game features.
Unfortunately, the time invested in the older systems is significant enough
that many of them are still around in some form or another. Through the
patch cycle, though, the default UI is being slowly reworked to use the newer
methods and, at some point in time, the old ways may no longer be supported.
Throughout this book we have purposefully omitted coverage of these past
practices. If you use the code for the default UI or other addons as research
material for your own addon, translate any usage of the constructs discussed
in the following sections into the newer method.
NOTE Rather than listing all deprecated systems in this section, specific events,
APIs, and so forth that should no longer be used are marked as deprecated in their
reference entries (see Part IV).
Global Widget Handler Arguments
The widget handler system you saw in Chapter 12 is new as of patch 2.0.
Instead of calling your handler with a self parameter and other related data
(button for OnClick,event and ... for OnEvent, and so on), the old system
used a global variable called this and several global argument variables (arg1,
arg2,andsoon).
There were a few problems with this approach. Using global variables for a
parameterized system does not make much sense conceptually, not to mention
their impact on performance. Also, the generic argnvariables go against the
very first pointer in this appendix. The only way for you to know the meaning
of the argument when reading old code is to look at a reference for the given
handler or hope you can infer its meaning from what the code does with it.
Following are two somewhat useless functions to illustrate the difference.
If you use SetScript to assign them to an OnHyperlinkClick script, they will
function identically.
function MyAddon_OnHyperlinkClick()
if arg3 == “LeftButton“ then
this.link = arg1
print(“You clicked on “..arg2)
end
end
Appendix A Best Practices 1325
function MyAddon_OnHyperlinkClick(self, link, text, button)
if button == “LeftButton“ then
self.link = link
print(“You clicked on “..text)
end
end
As you can see, this corresponds to self,arg1 corresponds to link,arg2
corresponds to text,andarg3 corresponds to button. With the exception of
the OnEvent handler, this and arg1-argnwill always match the parameter list
of the given handler. In this way, you can use the widget handler reference
in Chapter 31 to determine the meanings of the global arguments in any
legacy code. The only difference with OnEvent is that event always had its
own global. arg1-argn, in this case, correspond to the parameters passed
through ....
bag and slot Attributes on item Type Action Buttons
Another change in 2.1 is the simplification of secure action buttons with a
“type“ attribute of “item“. Previously, the “item“ attribute could only be
used to activate an item by name. To use an item in your inventory would
require a “slot“ attribute; to use an item in your bags required “bag“ and
“slot“ attributes. Now the “item“ attribute works the same way as the /use
macro command. It accepts an item name, item ID (in the form “item:12345“),
slot number, or bag and slot numbers separated by a space (for example,
“3 12“).
Again, for backward compatibility, the “bag“ and “slot“ attributes are
still supported. However, you should no longer use them; as a comment in
FrameXML\SecureTemplates.lua says, ‘‘Backward compatibility code, depre-
cated but still handled for now.’’ [Emphasis mine.]
Avoiding Common Mistakes
Addon authors can make dozens of common mistakes as they develop their
addons. Many of them have been covered throughout the book, but the
following deserve to be mentioned here, as well.
Adding Files While WoW Is Running
When World of Warcraft loads, it scans the file system and builds a table of
files that can be loaded during that session. If you add files while the game is
open, they won’t be part of that table and cannot be loaded or recognized by
the game. A related common mistake is adding a new file to your addon and
the Table of Contents file without fully exiting the game.
If you add files to the file system, make sure that you fully exit and restart
the game so that the changes will be fully registered.
1326 Part V Appendixes
Entering |into the Chat Edit Box
Because World of Warcraft uses the |character in its color codes and
hyperlinks, any that are entered in the edit box are automatically escaped
to a double ||. This can be problematic when running Lua scripts with the
/script and /run commands. You can substitute the sequence \124 instead of
the actual character to get around this limitation.
‘‘Missing’’ Frames
When you create a frame in your addon you expect it to be visible. If you can’t
find your frame, it may be missing due to not meeting one of the following
requirements:
The frame must have some visual component, such as a texture, backdrop,
or text element.
The frame must not be set as hidden in the XML file, or the frame’s Show()
method must have been called to explicitly show the frame.
Each frame that is a parent of the frame must also be shown. This includes
the frame’s parent, the parent’s parent, and so on.
The frame must be anchored somewhere within the bounds of the screen.
It’s easy to spend time digging through your code only to find later that
you’ve forgotten to place the frame on the screen.
Ignoring Logs\FrameXML.log
When working on XML, there are two places to check to ensure the file is being
parsed and validated properly:
Load the file in some program that can indicate that the file is well-formed.
This could include most web browsers or a more complex XML edi-
tor/validator.
Check the Logs\FrameXML.log file to ensure there weren’t any errors
parsing the file.
Not Checking API Returns
There are times when the Blizzard API functions may return something
other than what you’d expect. For example, there’s a small period of time
where UnitClass(unit) can return nil when you’d expect a class name to be
returned. If you use these function returns in some other computation, such as
indexing a table or calling another function, you may get an error somewhere
along the line.
Appendix A Best Practices 1327
In many cases, you can fix the problem by supplying default values in the
following way or by throwing an explicit error with the error() function:
local class = UnitClass(unit) or “Warrior“
Even if the class is wrong, you can be sure you won’t have an unexpected
error.
Requesting Data Before PLAYER_LOGIN
As stated in the earlier chapters, a number of functions don’t return the
correct results until the PLAYER_LOGIN event has fired. This can be remedied
by delaying the call until that point, but you should be aware when getting
unexpected results that the information may not be available in the client at
that moment.
Conflicting or Existing Anchor Points
Each frame can have multiple anchor points that help define the place-
ment or size of the frame. When adjusting anchor points, make certain that
you’ve cleared any that should no longer be set. When in doubt, run the
ClearAllPoints() method to ensure that a frame has no anchors before
adding your own anchor points.
APPENDIX
B
Utilizing Addon Libraries
When a system as incredibly complex as the World of Warcraft API is released,
inevitably someone writes a library of functions that makes it easier for specific
uses, or adds certain functionality. True to form, several addon frameworks
and libraries have been written for WoW. This appendix explores the creation
of libraries and introduces you to some of the more prevalent addon libraries.
What Is an Addon Library?
An addon library is a collection of code that can be used by multiple addons.
They tend to provide some abstraction over the Blizzard API that makes it
easier to use for common cases. Over the course of writing your addons you
may find yourself writing the same functions over and over again. Consider
the following:
function debug(...)
local succ, message = pcall(string.format, ...)
if succ then
print(“|cffff1100Debug: |r“, message)
else
print(“|cffff1100Debug: |r“, tostringall(...))
end
end
1329
1330 Part V Appendixes
I use a function similar to this in many of my addons. It’s an extension of
the built-in print function that prints a heading at the start of each message,
and also accepts format strings. This means instead of writing this:
print(string.format(“You have reached your destination '%s’“, destination)
Icanwritethis:
print(“You have reached your destination '%s’“, destination)
This function can be used to display a list of arguments in the same way as
the print function. Although it may not seem like much, I find printing to the
chat frame much easier using this function. This is how most libraries start,
identifying a piece of code that is useful to multiple addons and then writing
it in a way so it can be written once but distributed with each of them.
How Do Libraries Work?
There are two main types of libraries: those that are written as standalone
addons and use the dependency system to load properly, and those that
are packaged within the actual addon, typically referred to as embedded
libraries.
Each library scheme has its own set of benefits and tradeoffs, and no solution
has been found that fills everyone’s needs sufficiently. If your library is only
for personal use, and something you can easily control, making your library a
standalone addon is a natural choice. If you are using someone else’s library,
or know that other developers will use it, an embedded library gives you much
stricter control over what version of a library you are using.
Standalone Libraries
Libraries that are written as standalone addons are extremely easy to use and
to write. The following code shows a simple library that provides a way to use
the debug function written earlier in this appendix:
AddonUtils.toc
## Interface: 30200
## Title: AddonUtils
## Notes: A library of simple addon utilities
AddonUtils.lua
AddonUtils.lua
AddonUtils = {}
Appendix B Utilizing Addon Libraries 1331
function AddonUtils.createDebugFunc(prefix)
return function(...)
local succ, message = pcall(string.format, ...)
if succ then
print(“|cffff1100“ .. prefix .. “: |r“, message)
else
print(“|cffff1100“ .. prefix .. “: |r“, tostringall(...))
end
end
end
To avoid conflicts with other addons, you create a new global table called
AddonUtils. Inside you define a new function called createDebugFunc(),
which can be called by addons to create their own personalized debug
function. For example this could be used in the following way:
local debug = AddonUtils.createDebugFunc(“MyAddon“)
debug(“Hello World!“)
To use this library, an addon would need to include AddonUtils in its table
of contents file like so:
## Dependencies: AddonUtils
Advantages
Standalone addon libraries are very simple to create, and Blizzard’s depen-
dency system ensures that addons are loaded in the correct order. There is only
ever one version of the library loaded, so no special consideration is needed.
In addition, the library can have its own dependencies, define its own XML
templates, and store saved variables.
Disadvantages
The main problem with standalone addon libraries is the way they are
distributed. If you are including one with only a few of your addons and don’t
expect many changes to be required it can work out quite well. Unfortunately
if multiple authors might be including your library, or periodic changes are
necessary to the code it can be very frustrating. With a standalone addon you
have two ways to distribute it:
1. Direct the user to where he can download the latest version of the library
andmakehimresponsibleforitsupkeep.
2. Include the library alongside your own addon.
1332 Part V Appendixes
The first option requires the user to do more work to use your addon, but in
the day of addon updaters and email notification, this may not be a problem
for your application.
The second option is the more troublesome because it relies on other authors
including the most recent version with their addons. In addition, it’s a bit
confusing to users when they’re asked by the operating system if they want
to overwrite a file when installing the addon. This particular point is why
embedded libraries were created in the first place.
The distribution problem becomes much more important when multiple
versions of a library exist, without the name of the library addon changing.
You take the risk that the user (or some other addon) will include an older
version of a library you rely on.
Embedded Libraries
An embedded library is one that is included in any addon that uses it, rather
than stand alone as a separate addon. A system has been developed that uses
two pieces of information to ensure the system is robust:
Major versionA unique name that indicates the name and version of
the library. Two libraries with different major versions will run alongside
each other. For example: AddonUtils-1.0 or CommLib-2.0.
Minor versionA number that indicates the minor version of a given
library, with a higher value indicating a newer version. If two addons
have the same major version of a library but different minor versions,
the older one will be ‘‘upgraded’’ to the newer one using some defined
process.
In general, the major version should be updated whenever there is a change
to the behavior of the underlying functions or any other change that is
not backward-compatible with previous versions. The minor version is only
incremented when bugs are fixed or other minor changes are made.
Embedded Library Load Process
Here’s the general process for loading an embedded library:
1. Check to see if an instance of the library with the same major version is
already loaded.
2. If the same major version already exists, compare the minor version
numbers. If the new library being loaded has a matching minor version,
Appendix B Utilizing Addon Libraries 1333
or a lower minor version, the initialization process can safely return
immediately.
3. If a version exists but the minor version of the existing instance is less
than the one being loaded, then this instance should replace (or upgrade)
the existing instance with itself.
4. If the major version does not already exist, the library should simply be
loaded.
Using embedded libraries, multiple copies of the library may be loaded and
then thrown away, which can increase load times. This would only happen in
the situation where addons loaded in a specific order had increasing minor
versions of the same library. In addition, the library author needs to be sensitive
to the potential upgrade process, and should test the library thoroughly before
releasing a minor version update to a library.
Manually Versioning an Embedded Library
The code to manage the versioning of your library can be as simple as the
following:
local minor_version = 501
if MyLibraryName and minor_version < MyLibraryName.minor then
-- This version is old, so don’t load it
return
end
-- Library definition here
MyLibraryName = {}
function MyLibraryName.createDebugFunc(prefix)
return function(...)
local succ, message = pcall(string.format, ...)
if succ then
print(“|cffff1100“ .. prefix .. “: |r“, message)
else
print(“|cffff1100“ .. prefix .. “: |r“, tostringall(...))
end
end
end
end
In this case the major version name is MyLibraryName, and the minor version
is 501. The code first checks to see if the major version exists and, if it does,
compares the two minor versions. If the minor version being loaded is less
than the one that already exists, the code returns.
1334 Part V Appendixes
Versioning Using LibStub
In late 2007 the addon community banded together to create a simple stan-
dard way to register and access libraries, called LibStub. LibStub has three
functions:
LibStub:NewLibrary(major, minor)Attempts to register a new library
with the given major and minor versions. Returns a table that can be used
to store the library, or nil if the version being registered is not new.
LibStub:GetLibrary(major [, silent])Tries to get the library with
the given major version. The silent flag can be used to test for the
existence of a library without causing LibStub to raise an error.
LibStub:IterateLibraries()Returns an iterator over all the regis-
tered libraries.
The following shows how to define the same library using LibStub:
local major, minor = “MyLibraryName“, 1
local library = LibStub:NewLibrary(major, minor)
if not library then
-- This version is not new, so return
return
end
function library.createDebugFunc(prefix)
return function(...)
local succ, message = pcall(string.format, ...)
if succ then
print(“|cffff1100“ .. prefix .. “: |r“, message)
else
print(“|cffff1100“ .. prefix .. “: |r“, tostringall(...))
end
end
end
end
The library can then be used in the following way:
local MyLibraryName = LibStub:GetLibrary(“MyLibraryName“)
local debug = MyLibraryName.createDebugFunc(“MyAddon“)
With LibStub, if you register a major version that already has an existing
version you will receive the previous table back. You can then clear it,
define new functions, or handle any other tasks that are necessary for your
addon.
For more information about how to write libraries using LibStub, visit
www.wowwiki.com/LibStub.
Appendix B Utilizing Addon Libraries 1335
Using a Library
Rather than trying to give full details on a set of existing libraries, this section
introduces you to several different categories of libraries, giving you general
information about what each of them does.
Ace3
The Ace3 (www.wowace.com/projects/ace3) suite of libraries was designed to
be included as embedded libraries with minimal dependencies. This means
that you can include only those libraries you want to use rather than needing
to include the entire suite.
Ace3 includes libraries that provide the following functionality:
AceAddon-3.0An abstraction over addons that allow you to easily
disable and enable addons within the game without needing to reload
the user interface. Also provides a framework for modular components.
AceBucket-3.0Groups multiple events into ‘‘buckets.’’ This allows you
to watch for UNIT_HEALTH events, but only actually respond to them
periodically rather than every time an event fires.
AceComm-3.0A communications library that can handle arbitrarily
long messages. This library also throttles messages appropriately so the
sender is not disconnected.
AceConfigCmd-3.0Allows you to register a slash command definition
using a table, and have a slash command built automatically for you.
AceConfigDialog-3.0Generates a configuration GUI automatically
from a configuration table.
AceDB-3.0Manages saved variables for an addon, providing profiles,
smart defaults, and custom portions of the database that are custom
loaded for each character. This library can be quite useful if you’d like to
provide your users with the ability to load/clone/save addon profiles.
AceEvent-3.0Allows you to register for events and have custom func-
tions called when an event fires. This library is more of a convenience that
avoids you having to create a frame and write a custom OnEvent handler.
AceHook-3.0Library that allows you to hook and unhook functions
and scripts. Writing function hooks is not an easy endeavor and this
library helps to ensure good behavior.
AceTime-3.0Facility for creating and registering timers, so code can be
called in a delayed or repeating fashion.
The suite contains other, more special-purpose libraries. For more informa-
tion visit www.wowace.com/projects/Ace3.
1336 Part V Appendixes
Portfolio
Portfolio (www.wowinterface.com/downloads/info11749-Portfolio.html)al-
lows you to create configuration screens in the Blizzard Interface Options menu
with relative ease. It accepts a very straightforward configuration table format
and will automatically generate your GUI for you.
Dongle
Dongle (www.wowwiki.com/Dongle) is a collection of functions that should
be useful to anyone writing a new addon. Designed to be extremely small
without excess functionality, it provides an easy way to register events,
schedule tasks, and comes with a database system that makes creating saved
variable structures with defaults easy.
PeriodicTable
PeriodicTable (www.wowace.com/projects/libperiodictable-3-1)aimsto
add organization to items in World of Warcraft. It allows you to access them
via hierarchical sets (such as Consumable.Food.Edible.Cheese). This can be
useful when trying to figure out what categories an item might belong to,
in order to find out how best to use it. For example, it can help you identify
which common items are used in tradeskills.
BossIDs
The BossIDs library (www.wowace.com/projects/libbossids-1-0)justcon-
tains a list of all the mobs in the game that are considered ‘‘bosses,’’ because
there is no easy way to check this in-game. You can use the GUID of the mob
along with this library to make that determination.
LibHealComm
LibHealComm (www.wowace.com/projects/libhealcomm-3-0) provides ev-
ents and callbacks that allow you to get more information about the spells your
party and group members cast. Multiple users must have the library installed
to accomplish anything, but when the healers of a group have it installed it
makes it very easy to see who they are healing and at what time.
LibSharedMedia
LibSharedMedia (www.wowace.com/projects/libsharedmedia-3-0)isdesi-
gned to provide a way to construct a library of media files (sounds, tex-
tures, fonts) and allow multiple addons to access them. In this way, the addon
Appendix B Utilizing Addon Libraries 1337
developer simply uses the library if it exists to access the repository of media.
This allows users to select consistent graphics, fonts, and sounds depending
on their wants and needs.
Other Library Resources
Literally dozens of libraries have been written for any number of purposes,
and most of them are well documented and readily available. The best places
to explore for libraries to use are the following:
http://www.wowwiki.com/Function Library
www.wowace.com/categories/libraries
www.wowinterface.com/downloads/cat53.html
Some of these libraries depend on other libraries (which can get quite
messy), but if you’re looking for a good existing API for something that you
find peculiar in the Blizzard API, they may just have what you’re looking for.
APPENDIX
C
Tracking History Using Version
Control Systems
When you are creating your first few addons you’ll likely just create the files
on your machine and continue to add to them as the addon matures. If you
decide to release the addon, you’ll zip up that folder and post it somewhere for
the users to find it. This sort of process works great for very simple addons, but
once you start making larger addons or collaborating with other developers
you may find the need for something a bit more structured.
A standard technique for source code management in application develop-
ment is called version control. In version control systems, the developer creates
new snapshots throughout the development process and adds those snapshots
to the system. The code can be compared between snapshots, and developers
can use the snapshots to examine the history of an addon to better understand
how a bug or problem might have occurred.
Three main types of version control systems are used in the addon develop-
ment community: Subversion, Git, and Mercurial. This appendix introduces
the basic concepts of version control in each of them and points you toward
resources with more in-depth information.
Subversion
One of the more prevalent version control systems is Subversion, designed as
a replacement for the much older CVS version control system. This section
serves as a short guide to using Subversion; consult the full documentation
available at http://svnbook.red-bean.com.1339
1340 Part V Appendixes
One major point that must be made about Subversion is that, unlike the other
version control systems discussed later in this chapter, it requires a central
server for you to commit any changes. This may be a requirement you can live
with, but there are alternatives that enable you to make changes locally, and
then upload them to a server at a later time.
Terminology
The following is a list of terms that you will encounter when working with
Subversion, and reading this section.
RepositoryA central location that houses the version control system
(often shortened to repo). There is typically one repository per project or
addon, although this requirement is not hard and fast. The repository is
often located on a remote server and may have an address that looks like
one of the following:
http://hostname/repository/address
svn://hostname/repository/address
CommitWhen the developer makes changes to the local code and then
wants to push those changes into the central repository, he makes a
commit. A commit must include a log message that explains the changes
that are being committed. Commits aren’t expected every single time you
save the file on your machine, but rather at relevant stopping points (such
as when you’ve fixed a specific bug, or added a particular feature).
CheckoutA user or developer can download the current state of a
given repository by checking it out. This downloads the current files as
well as some basic history information. Typically, any user can check out
a repository, but only developers can commit.
Working copyThe local copy of the repository that a developer obtains
when checking out a Subversion repository.
DiffA file showing the differences between two versions of a given file
or two different states of a repository.
Layout of a Repository
The layout of a Subversion repository tends to include the following subdirec-
tories at the root level:
TrunkThe main development directory. This typically represents the
bleeding edge of development and should be used with care. It’s generally
meant for developers and testers only.
BranchesUsed when multiple versions of software are being worked
on at the same time. For example, if you’re still providing support for
Appendix C Tracking History Using Version Control Systems 1341
some stable version of your addon, you might make a branch to keep it
separate from your trunk development.
TagsTags are typically synonymous with releases, allowing you to see
the state of the source code at the point you released a version to the
public.
Obtaining Subversion
You can download Subversion for your platform from the main Subversion
website at http://subversion.tigris.org/getting.html. Packages exist for
both Mac OS X and Microsoft Windows machines. Once the package has been
installed, you can test that your system works properly by running the svn
command in a terminal or command window:
> svn
Type 'svn help’ for usage
If you see some other message, the command may not be in your path
and you’ll have to do a bit more experimentation. Several good guides to
installing and using Subversion on any system are linked directly from the
main Subversion website.
Command Primer
This section details the major Subversion commands you will use in the course
of daily development. As always, more detail is available using the svn help
command, or in the official documentation.
svn checkout <url>[path]
Checking out a Subversion repository is a matter of calling the svn checkout
command with the URL of the repository. By default, a folder is created with
the same name you are checking out, but you can specify a path argument to
use a different folder name instead. The following command checks out the
code for TomTom (one of my addons) into the folder trunk at your current
location:
svn checkout svn://svn.wowinterface.com/TomTom-17/trunk
Here’s a command that checks out the repository into a folder called TomTom
in your current directory:
svn checkout svn://svn.wowinterface.com/TomTom-17/trunk TomTom
The following command checks out the repository into the folder
C:\Subversion\TomTom on your computer:
svn checkout svn://svn.wowinterface.com/TomTom-17/trunk
c:\Subversion\TomTom
1342 Part V Appendixes
svn update [path]
The update command is used to update a working copy by contacting the
central server and downloading any changes that have been made since the
last update. By default, it updates whatever directory you are currently in
(assuming it’s a working copy).
If the current directory is a working copy, the following command updates
it to the latest revision:
svn update
This command updates the working copy in c:\Subversion\TomTom to the
latest revision:
svn update c:\Subversion\TomTom
svn add <path>
If you are creating files, rather than editing existing files, you will need to add
them to the system before you can commit them. You do this using the svn
add command. If you specify a filename, that file will be added. If you specify
a path, the path will be searched recursively, adding all files within that path.
The following command adds the file TomTom.lua to version control:
svn add TomTom.lua
This adds all files in the current directory (and beneath):
svn add .
Once files have been added to the system, they can be manipulated using
the other svn commands.
svn commit [path]
The commit command is used when you have changes that need to be pushed
to a central repository. On most systems, your default text editor will be
opened and you’ll be prompted for a commit message. Simply save the file in
the text editor and the commit will begin.
You may be prompted for a username or password if this is your first
commit. Whichever service runs your repository should be able to provide
you with this information. As usual, this command assumes the current
directory is a working copy, but a specific path can be specified.
svn status
To determine the state of the files in a repository, you can use the status
command. It can display what files have pending changes, what files are new,
Appendix C Tracking History Using Version Control Systems 1343
and what files might be missing (if any). Consult the Subversion documentation
for more information about the specific output of this command.
svn log [path]
The log command can be used to give a history of log messages for a working
copy. By default, it uses the current directory, but you can specify a specific
path if you choose. The following is a sample Subversion log for a few revisions
to the TomTom repository:
------------------------------------------------------------------------
r192 | Cladhaire-15704 | 2008-12-22 08:21:03 +0000 (Mon, 22 Dec 2008) | 2 lines
* Only try to set the corpse waypoint when c,z,x,y are positive numbers
------------------------------------------------------------------------
r191 | Cladhaire-15704 | 2008-12-21 21:41:53 +0000 (Sun, 21 Dec 2008) | 2 lines
* Added a Corpse arrow that can be configured on the general options screen.
When enabled, a non-persistent waypoint arrow will be set directing you toward
your corpse. It will be removed when you resurrect.
svn diff [path]
The diff command will print a listing of the differences between the code in
your working copy, versus the last commit to the repository. This is a handy
way to check what changes you’ve made to the file before committing.
Creating a Local Repository
Although Subversion is designed to be used with a central server, you
can actually create repositories locally on your machine using the svnadmin
command. The command takes a path that will serve as the destination of the
repository on the file system. The following command creates a new repository
in the C:\Subversion\MyAddon folder that can then be used to check out and
commit, assuming the C:\Subversion directory already exists:
svnadmin create C:\Subversion\MyAddon
Instead of using the http:// or svn:// type of URL, you use file:///
(note the extra / in the URL). To check out this repository, use the following
command:
svn checkout file:///c:/Subversion/MyAddon
You can now use this new repository to store your history without needing
to contact a remote server. This allows you to store a history of your code
locally so you can take advantage of the other features of Subversion.
1344 Part V Appendixes
Git and Mercurial
Git and Mercurial (hg) are distributed version control systems, which means
they do not need a central repository in order to function. By default, each
repository that is created contains the entire history of the project and can
function independent of each other. Both of these systems try to make it easy
for the developer to work with their code locally without needing access to a
remote server, while making it easy to submit changes to a project.
Mercurial began as a spin-off of the Git project so many of the commands
and much of the terminology is the same. Any differences between the two
systems are detailed in each individual section.
It should be noted that these two systems are relatively more complex than
Subversion and are a bit less user-friendly, however they can offer many
advantages as well.
Terminology
The terminology for Git and Mercurial differ a bit from that of Subversion.
RepositoryIn a distributed source code management system, a reposi-
tory refers to a copy of the source code and all of the historical information
about a project. Repositories can be cloned (copied), and the two reposi-
tories will be independent of each other.
CloneTo retrieve your own local copy of a repository you can clone
an existing one. This retrieves all of the data necessary to have your own
self-contained repository.
CommitWhen the developer makes changes to the local code and
then wants to push those changes into the central repository, he makes
a commit. A commit must include a log message that explains the
changes that are being committed. Commits aren’t expected every single
time you save the file on your machine, but rather at relevant stopping
points (such as when you’ve fixed a specific bug, or added a particular
feature).
DiffA file showing the differences between two versions of a given file
or two different states of a repository.
BranchA branch of development (for example you could create a
branch to add a new feature, or to fix a specific bug). Branches allow you
to segregate your development into different compartments that can later
be merged back together.
MergeMerging is a process where you take two divergent branches
and merge them back together into a single branch. This is useful when
working in a collaborative environment.
MasterMaster is the main branch in a Git repository.
Appendix C Tracking History Using Version Control Systems 1345
HEADThis is a special name for the most recent version of a branch.
For example, HEAD of master is the most recent commit in the master
branch.
Obtaining Git
Installing Git is a bit more complex than Subversion and varies wildly depend-
ing on operating system. Two main packages can be used to install Git for Mac
OS X:
http://metastatic.org/source/git-osx.html
http://code.google.com/p/git-osx-installer/
Both pages describe the installation procedure and should be straightfor-
ward. For Microsoft Windows, there is a package called msysgit that provides
an installation package at http://code.google.com/p/msysgit.
You can find documentation for Git in the Git User’s Manual at www.kernel.
org/pub/software/scm/git/docs/user-manual.html.
Obtaining Mercurial (hg)
You can find prebuilt packages for installing Mercurial at www.selenic.com/
mercurial/wiki/index.cgi/BinaryPackages. A number of methods of instal-
lation exist for both Microsoft Windows and Mac OS X.
You can find documentation for Mercurial online at http://hgbook.
red-bean.com.
Typical Usage
Curseforge (http://curseforge.com) is an addon development community
created by http://curse.com. It is the most likely place you will see addon
development using Mercurial and Git. Once you have created a new project
and it has been approved, you can create a new repository. Regardless of
whether you choose Git or Mercurial, you will be given two different URLs.
The first is the public address, which can be used by non-developers to follow
your project. The second is the development URL, which is used to actually
commit code to your project.
Git
To develop your addon with Git, you must first create a local repository that
contains your code. You can accomplish this by creating a new empty directory
and issuing the git init command.
> cd MyAddon
> git init
Initialized empty Git repository in /private/tmp/MyAddon/.git/
1346 Part V Appendixes
Once that’s done you can begin copying files in and making changes. Before
you can commit any files, you must notify Git that they should be tracked
using the git add command.
> git add MyAddon.toc
> git add MyAddon.lua
You can check the status of the repository using the git status command:
> git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use “git rm --cached <file>...“ to unstage)
#
# new file: MyAddon.lua
# new file: MyAddon.toc
#
Here the status shows that two new files are ready to be committed. You
can actually perform a commit using the git commit command:
> git commit -m “Adding empty files for MyAddon“
Created initial commit 5e48c92: Adding empty files for MyAddon
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 MyAddon.lua
create mode 100644 MyAddon.toc
This specifies the log message using the -m option, but you could just as
easily leave that off and Git will open a text editor for you to input the log
message.
Although this command made a commit to the local repository, there is still
nothing on the remote repository at Curseforge. To fix this, you can push the
current repository up to the remote location by using the git push command,
specifying the remote address and the branch you want to push:
> git push git@git.curseforge.net:wow/myproject/mainline.git master
Counting objects: 3, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 229 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To git@git.curseforge.net:wow/myproject/mainline.git
* [new branch] master -> master
This tells Git that you want to push the master branch to the remote location
specified. You will be prompted for your authentication information (this
Appendix C Tracking History Using Version Control Systems 1347
depends entirely on what host you are pushing to) and the master branch is
created on the remote repository.
In the future you can push new changes simply by running:
> git push git@git.curseforge.net:wow/myproject/mainline.git
If you are working collaboratively in the project, you can also retrieve any
new changes by running a git pull command:
> git pull git@git.curseforge.net:wow/myproject/mainline.git
Mercurial
The following process is very similar to Git but the output may differ slightly.
First, you must create a local repository that contains your code. You can
accomplish this by creating a new empty directory and issuing the hg init
command (there is no output from this command):
> cd MyAddon
> hg init
Once that’s done you can begin copying files in and making changes. Before
you can commit any files, you must notify Mercurial that they should be
tracked using the hg add command:
> hg add MyAddon.toc
> hg add MyAddon.lua
You can check the status of the repository using the hg status command:
> hg status
A MyAddon.lua
A MyAddon.toc
Here the status shows that two new files are waiting to be added. You can
actually perform a commit using the hg commit command (there is no output
unless there is an issue):
> hg commit -m “Adding empty files for MyAddon“
This specifies the log message using the -m option, but you could just as
easily leave that off and Mercurial will open a text editor for you to input the
log message.
Although this command made a commit to the local repository, there is still
nothing on the remote repository at Curseforge. To fix this, you can push the
current repository up to the remote location by using the hg push command,
specifying the remote address to which you want to push:
> hg push ssh://hg@hg.curseforge.net/wow/myproject/mainline.git
pushing to ssh://hg@hg.curseforge.net/wow/myproject/mainline
searching for changes
1348 Part V Appendixes
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 2 changes to 2 files
Now you tell Mercurial that you want to push the master branch to the
remote location specified. You will be prompted for your authentication
information (this depends entirely on what host you are pushing to) and the
master branch is created on the remote repository.
In the future you can push new changes simply by running:
> hg push git@git.curseforge.net:wow/myproject/mainline.git
If you are working collaboratively in the project, you can also retrieve any
new changes by running a hg pull command:
> hg pull git@git.curseforge.net:wow/myproject/mainline.git
APPENDIX
D
Addon Author Resources
Throughout the course of this book you’ve learned how to extend the default
user interface, and how to create new custom addons. Although we hope you
will continue using this book as a reference, other resources are available that
can help you as an addon author.
This appendix describes the various communities in which addon authors
can participate, and details the various ways in which you can distribute your
addon to a wide audience.
Community Websites
Over the course of the past five years, a large community has grown out of
the hundreds of devoted addon developers, and the multitude of addon users.
These forums and communities allow you to discuss addon development with
other developers, and allow users to contact their favorite developers.
World of Warcraft Forums
The Blizzard-sponsored WoW forums are extremely active, and we’re lucky
enough to have Blizzard employees who post somewhat regularly as they
make changes to the user interface. As a result, there are sticky posts that detail
the major changes in the last patch, as well as any upcoming changes that
1349
1350 Part V Appendixes
have already been announced. This allows authors to plan ahead and discuss
potential changes with the community and developers.
These forums are also a nice place to ask for and provide help with
addon writing, as well as to announce new projects and seek feedback on
existing ones. You can find the Official World of Warcraft UI forum at
http://forums.worldofwarcraft.com/board.html?forumId=11114.
WowProgramming Forums
Meant to allow readers of this book to talk with each other and converse with
the authors, a set of forums is available on the book’s companion website
(http://wowprogramming.com/forums). There you will find other like-minded
authors who are working through the same examples and documentation that
you are.
WoWInterface Forums
BecauseWoWInterface(www.wowinterface.com/forums/index.php)isdedi-
cated to user interface customization for WoW, it has quite a number of forums
devoted to different topics or modes of conversation. For example, it has its
own Chit-Chat forum, along with separate forums for Interface Help and
Interface Requests. Authors can discuss their released addons in the Released
Interfaces/Scripts forum. In addition, there is a set of six forums that focus on
developers helping developers.
There are a number of featured projects and authors on WoWInterface.com,
and each of them has its own forum to discuss the addon. This helps both the
reader and the developer stay more organized.
WowAce Forums
TheWowAceforums(http://forums.wowace.com) are dedicated to the discus-
sion of addon support and development. The site is separated into developer
and user sections to facilitate having a support thread and a very technical
discussion thread without causing confusion.
Curse Forums
Curse hosts its own UI forums (www.curse.com/forums/4900.aspx). However,
most discussion tends to take place on the WowAce forums, which is another
Curse website.
Elitist Jerks
The Elitist Jerks (http://elitistjerks.com/f32/)isanextremelycapable
World of Warcraft guild. It hosts a forum specifically for the discussion
Appendix D Addon Author Resources 1351
of user interfaces and addons that tends to be extremely active with both
announcements of new addons and discussion of the uses of existing ones. It
may not be the best place to go if you’re having difficulty installing or using
certain addons, but if you want to propose new addon ideas, or stay on the
bleeding edge of what’s being created, it may be just what you need.
IncGamers UI Customization Forums
Titled the ‘‘Unofficial World of Warcraft Forums,’’ the UI Customization
forums at IncGamers (http://wow.incgamers.com/forums/forumdisplay
.php?f=107) provide a way to generally discuss addons for WoW and another
sub-forum for authors to converse with each other. This splits the forums into
a less technical forum for assistance and a highly technical forum for those
who need it.
Internet Relay Chat (IRC)
For those who prefer more immediate feedback and discussion, a few channels
on IRC can be used to discuss addon development. Keep in mind that channel
activity fluctuates based on the time of day and the people who are available.
If you have a specific question, there is no need to ask for permission to ask it.
These channels are designed for questions and discussion, so don’t be timid.
#wowuidev on irc.freenode.net
#wowuidev on irc.freenode.net is a cross-community channel that is relatively
active, including developers from across the world. Here you can find the mod-
erators of the major addon websites (WowInterface, Curse, and IncGamers)
along with addon developers and users alike.
#wowace on irc.freenode.net
An interactive branch of the WowAce addon community, the #wowace on
irc.freenode.net channel tends to be used by those developers who write
addons using the Ace3 library framework and other associated libraries. Since
the release of the new WowAce development website, it is also used quite
heavily for that purpose.
#wowprogramming on irc.freenode.net
#wowprogramming on irc.freenode.net is a quieter channel on the same
network. You will find the authors of this book in this channel along with
other contributors and people who were involved in the book one way or
1352 Part V Appendixes
the other. Feel free to come and discuss topics in the book, or just to ask for
general help.
Distributing and Supporting Your Addon
Onceyouhaveanaddonwrittenyoumaywanttomakeitavailablesoother
users have access to it. You could post it on some free file-sharing website
or even post it on your own personal web space, but in time, you may find
yourself being overwhelmed with no easy way to provide support, accept
comments, or track bug reports and feature requests. Although distributing
can be different from these other details, this section illustrates a number of
options that make it easier to manage the distribution and support of your
addons.
WoW-Specific Hosting
Several of the websites that provide support and discussion for the addon
development community also provide the hosting of addon files. This section
introduces each of them with a bit of information about the services they
provide.
WoWInterface
The folks at WoWInterface (www.wowinterface.com) have been involved in
the MMORPG (massively multiplayer online role-playing games) community
since Everquest was initially released, and their World of Warcraft site brings
years of experience working with authors to the table. WoWInterface offers a
range of features specifically designed for addon authors, including a version
control system, feature and issues tracker, community forums, and per-project
comments.
Project Creation
There are two ways to create a project at WoWInterface:
Upload an existing addon.
Request a new project for development purposes.
Each addon project requires a description, screenshot, and other basic
information. All addons go through a manual approval process to ensure
there are no copyright or license violations, and that the addon listed is what’s
actually available for download.
Documentation
Each author portal can house any number of web pages with static content.
These are useful for introductions or other documentation for addons. There
Appendix D Addon Author Resources 1353
is also a frequently asked questions (FAQ) application that allows authors to
easily add questions and answers for each of their individual projects.
File Hosting
Almost every feature of WoWInterface focuses on the file hosting. Each addon
page offers a simple download button alongside links to the issues tracker,
author portal, and installation instructions. Each file can have up to five
screenshots and captions showcasing features of the addon.
If the addon has a Subversion system associated with it, the author can
publish new versions (and development versions) to the website directly,
without having to manually zip and package the addon. A development
version available for download is listed on the addon page.
CurseForge and WowAce
CurseForge (http://curseforge.com) and WowAce (http://wowace.com)are
two websites owned by Curse that cater to the needs of addon developers.
The two sites run the same software and the second is the newest genera-
tion of the ‘‘Ace’’ community, focused on addon development for World of
Warcraft. Curseforge is a more general-purpose development site for multiple
MMORPGs.
Because these sites are focused solely on addon development, their usage
is straightforward. Once you have created a project you can create a new
repository or just start uploading new files. All release-quality files you
upload are automatically syndicated to Curse.com.
IncGamers
Formerly known as ui.worldofwar.net, IncGamers (http://wowui.incgamers
.com) recently revamped its site to be more of an overall portal for various
computer games (including StarCraft II, Diablo II, and other Blizzard enter-
prises). The WoW interface portion of the site remains very specific and offers
a number of features that help addon authors.
Uploading a new addon is a simple process. First you upload the .zip file,
and it tries to automatically determine certain information about the addon
(such as the title and description) from your Table of Contents file. With much
of the information automatically filled in, the process is quick to complete.
Other Hosting Solutions
Following is a look at several other hosting solutions that might work for you.
Google Code
In March of 2007, Google entered the realm of open source project hosting at
http://code.google.com/hosting.Aslongasyouraddonisfreelyavailable
1354 Part V Appendixes
and open source, it offers Subversion hosting, a powerful issue tracking system,
and the stability of Google products. Although relatively new to the hosting
game, Google Code has already developed quite a following.
Open Source
All projects hosted on Google Code must be open source, and further must
have an open source license. As a result, you have only eight choices for
the licensing of your addon. Open source and software licensing topics are
beyond the scope of this book, but you may find some useful information at
www.wikipedia.org/wiki/Open source license.
Documentation
Each project created on Google Code has an attached wiki that can be used for
posting news, documentation, release notes, or for allowing the development
group to easily collaborate. The wiki is stored within the version control system
and, as a result, can be edited via the web or through the source directly.
The wiki uses a specific markup that is different from the MediaWiki
standard that has emerged, but it’s relatively easy to adapt.
Sourceforge
Created in November 1999, Sourceforge (http://sourceforge.net)wasthe
first large-scale collaborative open source software project hosting website.
Initially, it offered version control using CVS, and systems for documentation,
project management, and issue tracking. Over the past eight years it has
matured into a professional-scale software development system used by
thousands of open source projects.
Open Source
All projects hosted on Sourceforge must be open source, and further must
have an open source license. As a result, you have only eight choices for
the licensing of your addon. Open source and software licensing topics are
beyond the scope of this book, but you may find some useful information at
www.wikipedia.org/wiki/Open source license.
Project Creation
Creating a project at Sourceforge tends to take much longer than the alterna-
tives, in that it typically takes 15 to 30 minutes to complete. You are guided
through each step of the process with extensive documentation and help
to ensure you make the correct choices for your project. Sourceforge only
provides hosting to open source projects, so you must choose a compatible
license for your work. After you’ve chosen the category for your project and
provided descriptions and other information, your new project is submitted
for approval.
Appendix D Addon Author Resources 1355
The approval process can take anywhere from a few hours to a few days,
but this quality-control process ensures that the information for your project
is accurate and that the project will be properly categorized in the software
listing.
Personal Web Hosting
Of course, instead of using an existing website, you could choose to host your
files on your own, but each of the preceding sites has taken time to create
systems that are suited to the needs of addon authors. In addition, each of
those sites is relatively well known in the addon community, ensuring users
are comfortable downloading your addons.
If you choose to host your own files, you may want to consider adding the
following:
Forums for users to discuss your addons. It’s a very happy day when
your users step in and help support each other.
Issue tracking system that allows you to keep a to-do list of bugs to fix
and features to consider for later versions.
A mailing list or some other way for users to subscribe to be notified of
future updates.
Index
A
AbandonQuest, 556
AbandonSkill, 556
abs, Lua API, 999
absolute dimensions, sizing objects, 146
AcceptAreaSpiritHeal, 556557
AcceptArenaTeam, 557
AcceptBattlefieldPort, 557
AcceptDual, 557
AcceptGroup, 557
AcceptGuild, 557
AcceptLevelGrant, 557
AcceptLFGMatch, 557
AcceptQuest, 557
AcceptResurrect, 558
AcceptSockets, 558
AcceptTrade, 558
AcceptXPLoss, 558
Ace3 suite of libraries, 1335
achievement functions, 10251027
action (U) attributes,
SecureActionButtonTemplate, 292
action argument, UNIT_COMBAT event, 269
action buttons
making simple choices, 296298
modifying existing frame with, 299300
simplification of secure, 1325
action buttons, defining behaviors, 289295
action (U), 292
actionbar, 292
assist (U), 293
attribute, 294
cancelaura, 293
casting beneficial spell, 290
casting harmful spell, 290291
casting spell, 289290
click, 293
focus (U), 293
item (U), 292
item targets, 294
macro, 292293
mainassist (U), 293
maintank (U), 293
multispell, 292
overview of, 289
pet (U), 292
specifying units to affect, 291
spell (U), 292
stop, 293
target (U), 293
using ‘‘item’’ type button, 294295
using item with ‘‘macro’’ type button, 295
action functions, 10271028
ActionBar
functions, 1028
SecureActionButtonTemplate, 292
ActionButton_CalculateAction, 306307
ActionHasRange, 558
actionID, API meta-type, 542
actions, repeating, 4648
add command, Subversion, 1342
__add metamethod, 6971
AddChatWindowChannel, 558
AddChatWindowMessages, 559
AddDoubleLine(),GameTooltip, 455, 1177
AddFontStrings(),GameTooltip, 11771178
AddFriend, 559
AddHistoryLine(),EditBox, 1231
AddIgnore, 559
AddLine(),GameTooltip, 454455, 1178
AddMessage(),MessageFrame, 1223
AddMessage(),ScrollingMessageFrame,
12251226
AddMessage function, 360
1357
1358 Index A–A
AddMute, 559
addon libraries, 13291337
Ace3, 1335
BossIDs, 1336
Dongle, 1336
embedded, 13321334
LibHealComm, 1336
LibSharedMedia, 13361337
other resources for, 1337
overview of, 13291330
PeriodicTable, 1336
Portfolio, 1336
standalone, 13301332
understanding, 1330
add-on related functions, 10281029
ADDON_LOADED, 252253
ADDON_LOADED event, 250
AddonLoader, 130
addons
accessing selection screen, 127
BagBuddy. See BagBuddy addon
Blizzard, 810
code security, 463464
custom, 10
customizing user interface, 34
downloading and installing Lua interpreter,
14–15
example of creating, 1012
exploring your AddOns directory, 78
finding right functions through, 203
MapZoomOut, 367370
not making automatic decisions with, 7
slash commands and, 345
understanding, 4
what they can do, 47
WoW ‘‘Terms of Use’’ and, 7
addons, anatomy of, 125142
categories, 131132
files and folders, 125131
fontstrings, 139
frames, 138139
loading, 141142
localizing, 134138
responding to game events, 139140
widget scripts, 139
x-label directives, 131
XML files, 132134
addons, author resources
community websites, 13491351
Internet Relay Chat, 13511352
other hosting solutions, 13531355
WOW-specific hosting, 13521353
AddOns directory, 269270
AddOns subdirectory, 85
AddonUtils global table, 13301331
AddOrDelIgnore, 559
AddOrDelMute, 559560
AddOrRemoveFriend, 560
AddPreviewTalentPoints, 560
AddQuestWatch, 560
AddTexture(),GameTooltip, 1178
AddTrackedAchievement, 560561
AddTradeMoney, 561
Adobe Photoshop. See Photoshop
AdvanceTime(),Model, 11951196
agility tooltip, 452
ah-list-type, API meta-type, 543
aliases, 109110
AllowAttributeChanges(),Frame, 1146
Alpha Animation type, 12541255
alpha channels
creating with Adobe Photoshop, 377378
creating with Paint Shop Pro, 381382
textures and, 374
alphaMode texture attribute, buttons, 176
<Anchor> element, 147149
anchoring objects, 147149
anchorPoint, 543, 1327
anchors, pattern, 102, 139
and operator, 33, 390
angle brackets (<>), XML tags, 79
animation, creating templates for, 173
Animation types
Alpha, 12541255
Animation, 12431248
ControlPoint, 12501251
Path, 12481250
Rotation, 12511252
Scale, 12521253
Translation, 12531254
AnimationGroup, 12381242
API flags, common, 541
API functions. See also WoW (World of
Warcraft) API
creating faux scroll frames, 419422
failure to check returns, 13261327
secure, 475476
API meta-types
1nil, 542
actionID, 542
ah-list-type, 543
anchorPoint, 543
arenaTeamID, 543
auraFilter, 543544
backdrop, 544
binding, 545
bitfield, 544545
chatMsgType, 545
colorString, 545546
containerID, 546
containerSlotID, 546
frameStrata, 546
glyphIndex, 547
GUIDs (globally unique Identifiers), 547
Index AB 1359
hyperlink, 549552
inventoryID, 552
itemID, 553
itemLocation, 553556
itemQuality, 553554
itemString, 554
justifyH, 554
justifyV, 554
layer, 554
macroID, 554
overview of, 542555
powerType, 554
rollID, 555
spellbookID, 555
spellID, 555
standingID, 555
unitID, 555556
API reference conventions
argument and return listings, 540541
function signatures, 539540
overview of, 539
AppendText(),GameTooltip, 1178
ApplyBarberShopStyle, 561
AreaTeam_GetTeamSizeID, 562
AreaTeamDisband, 561
AreaTeamInviteByName, 561
AreaTeamLeave, 561
AreaTeamRoster, 561
AreaTeamSetLeaderByName, 562
AreaTeamUninviteByName, 562
arena functions, 10291030
arenaTeamID, API meta-type, 543
arg1 attribute, 440
arg2 attribute, 440
arguments
__newindex metamethod, 7475
accepting variable number of, 8182
API reference, 540541
combat events, 387388
declaring vararg function, 8283
functions using, 39, 4142
global widget handler, 13241325
metamethods, 67
reducing garbage with variable, 1312
setmetatable() function, 68
for statement, 49
UNIT_COMBAT event, 269
arithmetic metamethods, 7071
arithmetic operators, 2021, 339340
arrays, using tables as
adding elements to array, 5860
creating array, 57
defined, 56
getting length of array, 5758
removing elements from array,
60–61
sorting data, 8788
sorting elements of array, 61
traversing array part of table, 85
ArtBrowser, 155
AscendStop, 562
assert, Lua API, 999
assignment operator(=), 26
assist (U) attributes,
SecureActionButtonTemplate, 293
AssistUnit, 562
associative tables, 53
asterisk(*), 296297
AtBottom(),ScrollingMessageFrame, 1226
AttackTarget, 562
AtTop(),ScrollingMessageFrame, 1226
attribute,SecureActionButtonTemplate, 294
attributes
<Anchor>, 147149
choosing action by hostility, 298
CombatTrackerFrame, 271
delegating responsibility, 298
FontString, 164
frame, 288
frame vs. XML, 288
parent/child relationship, 145
template, 286, 288, 296297
text elements on dropdown menus, 438439
XML, 79
auction functions, 10301031
AURA_APPLIED, 394
AURA_APPLIED_DOSE, 394
AURA_BROKEN_SPELL, 395
AURA_REFRESH, 394
AURA_REMOVED, 394
AURA_REMOVED_DOSE, 394
auraFilter, API meta-type, 543544
authorized code. See snippets
AutoEquipCursorItem, 562563
autoFocus attribute, EditBox, 225
AutoLootMailItem, 563
automation, dropdown menu, 445447
AutoStoreGuildBankItem, 563
B
b(blue) attribute, ColorPicker, 441
backdrop, API meta-type, 544
backdrop, frame, 271272
BAG_UPDATE event, 246, 250, 354355
BagBuddy addon
opening, 251
overview of, 143
storing data, 251253
tracking changes to inventory, 246251
using items from, 253254
BagBuddy_bagCounts table, 248
BagBuddy_ItemTimes table, 248
BagBuddy_OnLoad(), 250251, 253254
1360 Index B–B
BagBuddy_Update()
adding OnEvent handler, 249250
altering, 248249
tracking new inventory items, 246248
using items from inventory, 253254
writing new sorting function, 248
BagBuddyItemTemplate, 175
BagBuddy.lua code
frame templates, 184
frames and graphics, 168
tracking new inventory items, 246251
widgets, 233237
WoW API, 204205
BagBuddy.toc code, 168
BagBuddy.xml code
frame templates, 184186
frames and graphics, 168169
widgets, 237241
bags
"bag" attribute, 1325
bag IDs, 193194
watching for changes in player’s, 354
writing bag scanner, 198201
bank functions, 10311032
BankButtonIDToInvSlotID, 563
barbershop functions, 1032
BarberShopReset, 563
battefield functions, 10321035
behavior, altering. See function hooking
beneficial spells, casting, 290291, 298
best practices, 13051327
avoiding adding files while WOW is running,
13251326
avoiding entering |into chat edit box, 1326
avoiding missing frames, 1326
avoiding requesting data before
PLAYER_LOGIN, 1327
breaking apart long functions, 1309
checking expected conditions first, 13191320
consistent programming style, 13091310
failure to check API returns, 13261327
failure to check Logs/FrameXML.log file, 1326
failure to clear existing anchor points, 1327
local variables, 13101311
minimizing unnecessary garbage, 13111317
named constants instead of literals, 13071308
recycling objects, 13171318
recycling tables, 13181319
reworking repetitive code, 13081309
shortcut evaluation, 13201322
variable name exceptions, 1307
variable names, meaningful, 13061307
WoW environment, 13231325
BindEnchant, 563564
binding, API meta-type, 545
binding keys and clicks to addon code. See key
binding
Bindings.xml, 332334
BindingTest.lua, 332334
BindingTest.toc, 330
BindingTest.xml, 330331
bitfield
API meta-type, 544545
combat logs, 389390
bits, combat logs and, 389
BlessedMenus code, 496499
Blizzard
addons, 810
disabled addons of, 67
interface art, 85
internal functions, 1035
XML User Interface Customization tool, 8586
Blizzard_DebugTools addon, 254255
blocks, scope, 36
BLP2 (.blp) graphics format, 86, 134, 373
boolean values and operators, 3335
BossIDs library, 1336
bracket ([[ ]]) quote marks, 3031
branches
Git and Mercurial terminology, 13441345
Subversion, 13401341
buff functions, 1035
BUILDING_DAMAGE, combat events, 391
BUILDING_HEAL, combat events, 392
Burning Crusade expansion pack to WoW, 6
button templates
creating for BagBuddy, 174177
TabButtonTemplate, 182
UICheckButtonTemplate, 181
UIPanelButtonTemplate, 180
UIPanelCloseButton template, 180
UIRadioButton template, 183
Button widget. See buttons
buttons
action. See action buttons
adding to dropdown menus, 433434
adding toggle button to dropdown menus,
432433
CombatTrackerFrame, 271
creating clickable, 212219
navigation, multiple pages, 219224
reference guide, 11641170
testing textures, 384
as widget type, 227228
buttons, interactive, 207212
overview of, 207208
setting frame scripts via Lua, 209
setting frame scripts via XML, 208
showing item tooltips, 210212
using function attribute, 209
BuybackItem, 564565
BuyGuildBankTab, 564
BuyGuildCharter, 564
BuyMerchantItem, 564
Index BC 1361
BuyPetition, 564
BuyStableSlot, 564
BuyTrainerService, 564
bypassing metatables, 7576
C
cache, for frequently accessed values, 1322
calculate function, 340341
CalculateAuctionDeposit, 565
calendar functions, 10361040
CalendarAddEvent, 565
CalendarCanAddEvent, 565
CalendarCanSendInvite, 565
CalendarCloseEvent, 565566
CalendarContextDeselectEvent, 566
CalendarContextEventCanComplain, 566
CalendarContextEventCanEdit, 566567
CalendarContextEventClipboard, 567
CalendarContextEventComplain, 567
CalendarContextEventCopy, 567
CalendarContextEventGetCalendarType, 568
CalendarContextEventPaste, 568
CalendarContextEventRemove, 569
CalendarContextEventSignUp, 569
CalendarContextGetEventIndex, 569570
CalendarContextInviteAvailable, 570
CalendarContextInviteDecline, 570
CalendarContextInviteIsPending, 571
CalendarContextInviteModeratorStatus, 571
CalendarContextInviteRemove, 572
CalendarContextInviteStatus, 572
CalendarContextInviteType, 573
CalendarContextSelectEvent, 573
CalendarDefaultGuildFilter, 574
CalendarEventAvailable, 574
CalendarEventCanEdit, 574
CalendarEventCanModerate, 574
CalendarEventClearAutoApprove, 574
CalendarEventClearLocked, 574
CalendarEventClearModerator, 574575
CalendarEventDecline, 575
CalendarEventGetCalendarType, 575
CalendarEventGetInvite, 575576
CalendarEventGetInviteResponseTime, 576
CalendarEventGetInviteSortCriterion, 576
CalendarEventGetNumInvites, 576
CalendarEventGetRepeatOptions, 576
CalendarEventGetSelectedInvite, 577
CalendarEventGetStatusOptions, 577
CalendarEventGetTextures, 577
CalendarEventGetTypes, 577
CalendarEventHasPendingInvite, 577
CalendarEventHaveSettingsChanged, 578
CalendarEventInvite, 578
CalendarEventIsModerator, 578
CalendarEventRemoveInvite, 578
CalendarEventSelectInvite, 578
CalendarEventSetAutoApprove, 579
CalendarEventSetDate, 579
CalendarEventSetDescription, 579
CalendarEventSetLocked, 579
CalendarEventSetLockoutDate, 579
CalendarEventSetLockoutTime, 579
CalendarEventSetModerator, 580
CalendarEventSetRepeatOption, 580
CalendarEventSetSize, 580
CalendarEventSetStatus, 580
CalendarEventSetTextureID, 581
CalendarEventSetTime, 581
CalendarEventSetTitle, 581
CalendarEventSetType, 581
CalendarEventSignUp, 581
CalendarEventSortInvites, 582
CalendarFirstPendingInvite, 586
CalendarGetAbsMonth, 582
CalendarGetDate, 582
CalendarGetDayEvent, 582584
CalendarGetEventIndex, 584
CalendarGetEventInfo, 585586
CalendarGetHolidayInfo, 586587
CalendarGetMaxCreateDate, 587
CalendarGetMaxDate, 587
CalendarGetMiniDate, 587588
CalendarGetMiniHistoryDate, 588
CalendarGetMonth, 588
CalendarGetMonthName, 588
CalendarGetNumDayEvents, 588589
CalendarGetNumPendingInvites, 589
CalendarGetRaidInfo, 589
CalendarGetWeekdayNames, 589590
CalendarIsActionPending, 590
CalendarMassInviteArenaTeam, 590
CalendarMassInviteGuild, 590
CalendarNewEvent, 590
CalendarNewGuildAnnouncement, 590
CalendarNewGuildEvent, 591
CalendarOpenEvent, 591
CalendarRemoveEvent, 591
CalendarSetAbsMonth, 591
CalendarSetMonth, 591
CalendarUpdateEvent, 591592
CallCompanion, 592
camera functions, 10401041
CameraOrSelectOrMoveStart, 592
CameraOrSelectOrMoveStop, 592
CameraZoomIn, 592593
CameraZoomOut, 593
CanAlterSkin, 593
CanCancelAuction, 593
CancelAreaSpiritHeal, 600
CancelAuction, 600
cancelaura attributes,
SecureActionButtonTemplate, 293
1362 Index C–C
CancelBarberShop, 600
CancelDuel, 600
cancelFunc attribute, ColorPicker, 442
CancelItemTempEnchantment, 600
CancelLogout, 601
CancelPendingEquip, 601
CancelPendingLFG, 601
CancelPetAction, 602
CancelShapeShiftForm, 601, 602
CancelSummon, 601
CancelTrade, 601
CancelTradeAccept, 601
CancelUnitBuff, 601602
CanChangeAttribute(),Frame, 1146
CanChangeProtectedState(),Region, 1124
CanComplainChat, 593
CanComplainInboxItem, 594
CanEditGuildEvent, 594
CanEditGuildInfo, 594
CanEditGuildTabInfo, 594
CanEditMOTD, 594
CanEditOfficerNote, 595
CanEditPublicNote, 595
CanEjectPassengerFromSeat, 595
CanExitVehicle, 595
CanGrantLevel, 595
CanGuildBankRepair, 595
CanGuildDemote, 596
CanGuildInvite, 596
CanGuildPromote, 596
CanGuildRemove, 596
CanHearthAndResurrectFromArea, 596
CanInspect, 596597
CanJoinBattlefieldAsGroup, 597
CanMerchantRepair, 597
CanNonSpaceWrap() method, FontString, 1136
CanQueueForWintergrasp, 597
CanSaveTabardNow() method, TabardModel,
1203
CanSendAuctionQuery, 597598
CanSendLFGQuery, 598
CanShowAchievementUI, 598
CanShowResetInstances, 598
CanSignPetition, 599
CanSummonFriend, 599
CanSwitchVehicleSeat, 599
CanSwitchVehicleSeats, 599
CanUseEquipmentSets, 599600
CanViewOfficerNote, 600
CanWithdrawGuildBankMoney, 600
CanWordWrap() method, FontString, 1136
capture
pattern, 101
utility function, 361362
case sensitivity
named constants, 1308
XML tags, 79
CAST_FAILED, combat events, 392
CAST_START, combat events, 391
CAST_SUCCESS, combat events, 391
CastSpell, 602
CastSpellByID, 602603
CastSpellByName, 291, 303304, 603
categories, addon, 131132
categories, API
achievement functions, 10251027
action functions, 10271028
ActionBar functions, 1028
add-on related functions, 10281029
arena functions, 10291030
auction functions, 10301031
bank functions, 10311032
barbershop functions, 1032
battefield functions, 10321035
Blizzard internal functions, 1035
buff functions, 1035
calendar functions, 10361040
camera functions, 10401041
channel functions, 10411043
chat functions, 10431044
class resource functions, 1045
client control and information functions,
10451046
combat functions, 1046
CombatLog functions, 1046
companion functions, 1047
container functions, 10471048
currency functions, 10481049
cursor functions, 10491051
CVar functions, 10351036
debugging functions, 10511052
duel functions, 1052
equipment manager functions, 10521053
faction functions, 10531054
flight functions, 1105
Glyph functions, 10541055
GM survey functions, 1054
GM ticket functions, 1054
guild bank functions, 10551056
guild functions, 10561059
hyperlink functions, 10591060
in-game movie playback functions, 1060
inspect functions, 10601061
instance functions, 1061
inventory functions, 10611062
item functions, 10631064
item text functions, 1063
keybind functions, 1065
keyboard functions, 10651066
Knowledge-base functions, 10661067
limited play time functions, 1067
locale-specific functions, 1067
looking for group functions, 10681069
loot functions, 10691070
Index CC 1363
Lua library functions, 10701072
Mac client functions, 10721073
macro functions, 10731074
mail functions, 10741075
map functions, 10751076
merchant functions, 10761077
modified click functions, 1078
money functions, 10781079
movement functions, 10791080
multi-cast action, 1080
NPC ‘‘gossip’’ dialog functions, 10801081
objectives tracking functions, 1081
party functions, 1082
pet functions, 10831084
pet stable functions, 1083
petition functions, 1085
player information functions, 10851088
profiling functions, 10511052
PvP functions, 10881089
quest functions, 10891093
raid functions, 10941095
recruit-a-friend functions, 1095
secure execution utility functions, 10951096
shapeshift functions, 1101
skill functions, 1096
social functions, 10961097
socketing functions, 10971098
sound functions, 10981099
spell functions, 10991101
stance functions, 1101
stat information functions, 11011103
summoning functions, 1103
talent functions, 11031104
targeting functions, 11041105
taxi functions, 1105
threat functions, 1105
tracking functions, 1106
trade functions, 11061107
tradeskill functions, 11071108
trainer functions, 11081110
tutorial functions, 1110
UI/visual functions, 1110
unit functions, 11101113
utility functions, 11131115
vehicle functions, 11151116
video functions, 11161117
voice functions, 11171119
zone information functions, 1119
ceil, Lua API, 999
Celsius, converting to Fahrenheit, 4142
ChangeActionBarPage, 603
ChangeChatColor, 603
channel functions, 10411043
ChannelBan, 603
ChannelInvite, 603604
ChannelKick, 604
ChannelModerator, 604
ChannelMute, 604
ChannelSilenceAll, 604
ChannelSilenceVoice, 604605
ChannelToggleAnnouncements, 604605
ChannelUnban, 605606
ChannelUnmoderator, 606
ChannelUnmute, 606
ChannelUnSilenceAll, 605
ChannelUnSilenceVoice, 605
ChannelVoiceOff, 606
ChannelVoiceOn, 606
character classes, patterns, 98100
chat edit box, 225226
chat functions, 10431044
ChatFrame, as widget type, 231
ChatFrame_AddMessageEventFilter, 606607
ChatFrame_GetMessageEventFilters, 607608
ChatFrame_RemoveMessageEventFilters, 608
chatMsgType, API meta-type, 545
CheckBinderDist, 608
checkboxes
creating, 181
understanding CheckButton, 228
CheckButton
dropdown menus, 440441
overview of, 11701172
as widget type, 228
CheckInbox, 608
CheckInteractDistance, 608
checkouts, Subversion, 1340
CheckReadyCheckTime, 609
CheckSpiritHealerDist, 609
CheckTalentMasterDist, 609
child elements, 415416
chunks, scope of, 37
class resource functions, 1045
classes, patterns using character, 98100
Clear(),MessageFrame, 1223
Clear(),ScrollingMessageFrame, 1226
ClearAchievementComparisonUnit, 609
ClearAllPoints(),Region, 1124
ClearArenaTeamRoster, 613
ClearAuctionHouse, 613
ClearAuctionSellItemButton, 611
ClearCursor, 609
ClearFGAutojoin, 610
ClearFMAutofill, 610
ClearFocus, 609, 1231
ClearFog(),Model, 1196
ClearInspectPlayer, 609
ClearLandmark, 611
ClearLines(),GameTooltip, 1178
ClearLookingForGroup, 610
ClearLookingForMore, 610
ClearModel(),Model, 1196
ClearOverrideBindings, 610
ClearPartyAssignment, 610
1364 Index C–C
ClearSendMail, 610
ClearSendMailItemButton, 611612
ClearSocketButton, 612
ClearStablePet, 612
ClearTarget, 610
ClearTradeButton, 613
ClearTutorials, 610
Click(),Button, 11641165
click attributes, SecureActionButtonTemplate,
289290, 293
click events, 511512
click handlers, 221, 468473
click responders. See event and click responders,
frames
click wrapper, 483484
clickable buttons, 212219
ClickAuctionSellItemButton, 611
ClickBindingTest.lua, 335
ClickBindingTest.toc, 334
ClickLandmark, 611
ClickSendMailItemButton, 611612
ClickSocketButton, 612
ClickStablePet, 612
ClickTargetTradeButton, 612613
ClickTradeButton, 613
client control and information functions,
10451046
client locales, 135
clones, Git and Mercurial, 1344
CloseArenaTeamRoster, 613
CloseAuctionHouse, 613
CloseBankFrame, 613
CloseBattlefield, 614
CloseGossip, 614
CloseGuildBankFrame, 614
CloseGuildRegistrar, 614
CloseItemText, 614
CloseLoot, 614
CloseMail, 614
CloseMerchant, 614615
ClosePetition, 615
ClosePetitionVendor, 615
ClosePetStables, 615
CloseQuest, 615
CloseSocketInfo, 615
CloseTabardCreation, 615
CloseTaxiMap, 615
CloseTrade, 615
CloseTradeSkill, 615
CloseTrainer, 615616
closures, minimizing unnecessary garbage,
13111312
code
MapZoomOut, 371372
repeating with OnUpdate scripts,
356357
secure vs. tainted, 286
securing addon, 463464
SquareUnitFrames, 526535
Cogwheel’s Complete Macro Guide, 295
CollapseAllFactionHeaders, 616
CollapseChannelHeader, 616
CollapseFactionHeader, 616
CollapseQuestHeader, 616
CollapseSkillHeader, 616
CollapseTradeSkillSubClass, 616617
CollapseTrainerSkillLine, 617
collectgarbage, Lua API, 9991000
colon operator (:), 65–67
color
enhancing textures with, 158160
showing with textures, 139
<Color> element, 158160, 165
colorCode attribute, dropdown menus, 438
ColorFloat type, 84
ColorPicker, dropdown menus, 441443
ColorSelect frame type, 228229, 11721175
colorString, API meta-type, 545546
ColorType,84
combat events
arguments, 387388
prefixes, 389390
responding to events with OnEvent, 408409
special combat events, 395396
sub-events, 388
suffixes, 390393
suffixes for SPELL prefix, 393395
combat functions, 1046
combat log
combat event prefixes, 389390
combat event suffixes, 390393
combat event suffixes for SPELL prefix,
393395
COMBATLOG_OBJECT_AFFILIATION_MASK, 399
COMBATLOG_OBJECT_CONTROL_MASK, 398
COMBATLOG_OBJECT_ISA, 400
COMBATLOG_OBJECT_REACTION_MASK, 399
COMBATLOG_OBJECT_TYPE_MASK, 398
event arguments, 387388
overview of, 387
special combat events, 395396
summary, 412
unit flags, 398
unit GUIDs, 396397
Combat Status addon, 401412
creating basic structure, 401402
creating frame display, 410
future additions to, 412
initializing, 402404
overview of, 401
responding to events with OnEvent, 408409
sections of, 409410
snapshots of damage and healing, 407
Index CC 1365
storing damage and healing information,
405407
updating frame display, 410412
updating pet mappings, 405
writing OnUpdate function, 408
combat tracking, testing, 280
COMBAT_LOG_EVENT, 387
COMBAT_LOG_EVENT_UNFILTERED, 387, 409
combatEvent argument, 388
CombatLog functions, 1046
COMBATLOG_OBJECT_AFFILIATION_MASK, 399
COMBATLOG_OBJECT_CONTROL_MASK, 398
COMBATLOG_OBJECT_ISA, 400
CombatLog_Object_IsA, 619620
COMBATLOG_OBJECT_REACTION_MASK, 399
COMBATLOG_OBJECT_TYPE_MASK, 398
CombatLogAddFilter, 617
CombatLogAdvanceEntry, 617
CombatLogClearEntries, 618
CombatLogGetCurrentEntry, 618
CombatLogGetNumEntries, 618
CombatLogGetRetentionTime, 618
CombatLogResetFilter, 619
CombatLogSetCurrentEntry, 619
CombatLogSetRetentionTime, 619
CombatTextSetActiveUnit, 620
CombatTracker addon, 267281
adding functions to CombatTracker.lua,
275278
adding script handlers to
CombatTrackerFrame, 273274
creating skeleton, 269270
defining specifications, 267269
defining XML frame, 270272
testing, 278281
testing CombatTrackerFrame, 272273
CombatTracker_OnEvent(), 276278
CombatTracker_OnLoad(frame), 275276
CombatTracker_ReportDPS(), 278
CombatTracker_UpdateText(), 277278
CombatTrackerFrame, 270273
CombatTracker.lua
adding functions, 275278
adding script handlers, 273274
creating, 270
CombatTracker.xml, 270271
command tables, slash commands, 345347
commands
running Lua, 18
Subversion, 13411343
commas, in table constructors, 56
comments
encouraging users to use localization, 136
using consistent programming style, 1310
commit command, Subversion, 1342
commits, 1340, 1344
community websites, 13491351
companion functions, 1047
comparison functions, 8889
comparison operators, 2627
ComplainChat, 620
ComplainInboxItem, 620
complaint functions, 1047
CompleteQuest, 620
complex expressions, 44
components, XML, 112113
__concat metamethod, 72
concatenation (...) operator, 28
conditionals
checking expected, 13191320
complex expressions, 44
extended, 4445
shortcut evaluation optimizing, 13201322
simple, 43–44
in triggered changes, 490496
verifying arguments to functions, 4546
ConfirmAcceptQuest, 621
ConfirmBinder, 621
ConfirmBindOnUse, 621
ConfirmLootRoll, 621
ConfirmLootSlot, 621
ConfirmReadyCheck, 621
ConfirmSummon, 621622
ConfirmTalentWipe, 622
/console reloadui, 279
ConsoleAddMessage, 622
ConsoleExec, 622
constants, named, 13071308
container API, 193
container functions, 10471048
containerID, API meta-type, 546
ContainerIDToInventoryID, 622
ContainerRefundItemPurchase, 622623
containerSlotID, API meta-type, 546
content, tooltip, 453
contextual tooltips, 452
control structures
if statement, 4346
role in secure environment, 476477
for statement, 4851
while statement, 4648
ControlPoint, 12501251
ConvertToRaid, 623
Cooldown type, 11751176
CopyFontObject(),Font, 12211222
Corel Paint Shop Pro. See Paint Shop Pro
counters, improving, 67
CREATE, combat events, 393
CreateAnimation(),AnimationGroup,
12381239
CreateAnimationGroup(),Region, 1124
CreateControlPoint(),Path, 1249
CreateFont, 623
CreateFontString(), 166, 1146
1366 Index C–D
CreateFrame, 172, 623
CreateMacro, 624
CreateTexture(),Frame, 1146
CreateTitleRegion(),Frame, 1147
creeping taint, 307308
cross-realm players, 1323
Ctrl+ R, viewing framerate, 351
currency functions, 10481049
Curse forums, 1350
CurseForge, 1345, 1353
cursor functions, 10491051
CursorCanGoInSlot, 624
CursorHasItem, 624
CursorHasMacro, 624625
CursorHasMoney, 625
CursorHasSpell, 625
custom text, in tooltips, 453455
CVar functions, 10351036
CycleVariation(),TabardModel, 1203
D
DAMAGE, combat events, 391
damage and healing information, storing,
405407
damage argument, UNIT_COMBAT event, 269
DAMAGE_SHIELD, 395
DAMAGE_SHIELD_MISSED, 396
DAMAGE_SPLIT, 396
damagetype argument, UNIT_COMBAT event, 269
database sites for WoW, 195
date, Lua API, 1000
dead players, 519521
debugging functions, 10511052
debugprofilestart, Lua API, 1000, 1001
debugprofilestop, Lua API, 1001
debugstack, Lua API, 10011002
debugstack() function, 109
decision-making. See if statement
DeclineArenaTeam, 625
DeclineGroup, 625
DeclineGuild, 625
DeclineInvite, 625
DeclineLevelGrant, 625
DeclineLFGMatch, 625
DeclineName, 626
DeclineQuest, 626
DeclineResurrect, 626
default state, setting addon, 130
## DefaultState: directive, addons, 130
definitions, XML, 220
deg, Lua API, 1002
Delay(), viewing framerate, 352
DeleteCursorItem, 627
DeleteEquipmentSet, 627
DeleteGMTicket, 627
DeleteInboxItem, 627
DeleteMacro, 627
DelIgnore, 626
DelMute, 627
DemoteAssistant, 627
dependencies, addon, 126127
## Dependencies: directive, addons, 128129
DepositGuildBankMoney, 628
deprecated code, avoiding, 13241325
DescendStop, 628
destFlags argument, combat events, 388
destGUID argument, combat events, 388
destName argument, combat events, 388
DestroyTotem, 628
DetectWowMouse, 628
diff command, Subversion, 1343
diff file, 1340, 1344
difftime, Lua API, 1002
directories
Blizzard addon, 810
CombatTracker, 269270
creating addon, 1011
custom addon, 10
exploring your addon, 78
Disable(),Button, 1165
Disable(),Slider, 1216
DisableAddOn, 628
DisableAllAddOns, 628629
disabled attribute, dropdown menus, 438
DisableDrawLayer(),Frame, 1147
DisableSpellAutocast, 629
DismissCompanion, 629
Dismount, 629
DISPELL, combat events, 395
DISPELL_FAILED, combat events, 395
display attributes, secure group header, 504505
DisplayChannelOwner, 629
DisplayChannelVoiceOff, 629
DisplayChannelVoiceOn, 629
distribution
of addons, 13521355
standalone addon library disadvantages,
13311332
__div metamethod, 6971
Document Type Definition (DTD), XML
document validation, 81
documentation, 13521354
documents, validating XML, 115117
DoEmote, 629630
Dongle library, 1336
DoReadyCheck, 630
DoTradeSkill, 630
double (‘‘) quote marks, strings, 30
DownloadSettings, 630
DRAIN, combat events, 393
Dress(),DressUpModel, 1202
DressUpModel type, 11751176
DropCursorMoney, 630
Index DE 1367
dropdown frames, 433
dropdown menus
adding functionality, 437
adding toggle button, 432433
automating creation of, 445447
CheckButton menu items, 440441
ColorPicker menu items, 441443
creating, 431432
creating dropdown frame, 433
creating dynamic menus, 447448
creating multilevel, 436437
customizing text elements, 438439
function menu items, 440
initializing dropdown, 433434
overview of, 431
for selection, 443445
summary, 449
testing, 435436
toggling, 434435
DropDownTest addon, 435
DropItemOnUnit, 630631
DTD (Document Type Definition), XML
document validation, 81
duel functions, 1052
DURABILITY_DAMAGE, 394
DURABILITY_DAMAGE_ALL, 394
dynamic menus, 447448
E
EasyMenu, 445447
EditBox
creating, 225226
reference guide, 12311238
as widget type, 229
EditMacro, 631
EjectPassengerFromSeat, 631
elements
adding array, 5860
creating from tables, 5455
removing array, 6061
sorting array, 61
XML, 79
Elitist Jerks, 1350
embedded addon libraries, 13321334
embedded libraries, 1330
Enable(),Button, 1165
Enable(),Slider, 1216
EnableAddOn, 631
EnableAllAddOns, 631632
EnableBoundTradeable, 632
EnableDrawLayer(),Frame, 1147
EnableJoystick(),Frame, 1147
EnableKeyboard(),Frame, 1147
EnableMouse(),Frame, 1148
enableMouse attribute, CombatTrackerFrame,
271
EnableMouseWheel(),Frame, 1148
EnableSpellAutocast, 632
EnableSubtitles(),MovieFrame, 1205
ENCHANT_APPLIED, combat events, 396
ENCHANT_REMOVED, combat events, 396
end keyword, creating functions, 40
end_value,for loops, 50
EndRefund, 632
ENERGIZE, combat events, 392
entities, XML, 80
EnumerateFrames, 632633
EnumerateServerChannels, 633
environment, private global, 474475
ENVIRONMENTAL, combat events, 389
equality operators, 27, 35
EquipCursorItem, 633
EquipItemByName, 633
Equipment Manager, 355, 10521053
EquipmentManager_UnpackLocation, 634635
EquipmentManagerClearIgnoredSlotsForSave,
634
EquipmentManagerIgnoreSlotsForSave, 634
EquipmentManagerIsSlotIgnoredForSave, 634
EquipmentManagerUnignoreSlotForSave, 634
EquipmentSetContainsLockedItems, 635
EquipPendingItem, 633634
error, Lua API, 1002
error() function, 4546, 1327
error messages, 1819, 133
errorState flag, 343
escapes, string, 3032
event and click responders, frames
health update events, 513514
moving the header, 512513
name changes, 516
overview of, 511
power update events, 514516
targeting unit on left click, 511512
events, responding to, 243255
addons, 139140
combat. See combat events
finding right, 254255, 268269
grouping multiple, 355356
grouping to avoid over-processing, 354355
health update, 513514
with OnEvent, 244245
overview of, 243244
power update, 514516
query, 246
query events, 246
registering for, 244
storing data with SavedVariables, 251253
tracking changes to inventory for BagBuddy,
246251
understanding, 243244
using frames, 139140
using items from BagBuddy, 253254
1368 Index E–F
events reference, 12771301
/eventtrace, 245, 254255
execution taint, 304305
exp, Lua API, 1002
ExpandAllFactionHeaders, 635
ExpandChannelHeader, 635
ExpandCurrencyList, 635636
ExpandFactionHeader, 636
ExpandQuestHeader, 636
ExpandSkillHeader, 636
ExpandTradeSkillSubClass, 636
ExpandTrainerSkillLine, 636637
explicit-1() value, Frame:IsProtected()
method, 287
expressions, complex, 44
extended conditionals, 4445
eXtensible Markup Language. See XML
(eXtensible Markup Language)
EXTRA_ATTACKS, combat events, 394
F
faction functions, 10531054
FactionToggleAtWar, 637
factorial() function
computing factorials, 4647
looping with numeric for statement, 4849,
50
while loop vs. repeat,48
factory function, 67
FadeOut(),GameTooltip, 1178
Fahrenheit, converting Celsius to, 4142
faux scroll frames, 413, 419422
files
avoiding adding while game is running,
13251326
checking to ensure proper parsing,
1326
implementing localization, 136
files, addon, 125131
## DefaultState: directive, 130
## Dependencies: directive, 128129
## Interface: directive, 126127
## LoadManager: directive, 130
## LoadOnDemand: directive, 129
## LoadsWith: directive, 129130
## Notes: directive, 128
## OptionalDeps: directive, 129
## RequiredDeps: directive, 128129
## SavedVariables: directive, 130
## SavedVariablesPerCharacter: directive,
131
## Title: directive, 127
creating, 1011
table of contents (TOC) file, 125126
FillLocalizedClassList, 637
filter buttons, 214219, 224
filters
adding name, 224227
predefined combat log, 400
for secure group header, 503
Finish(),AnimationGroup, 1239
first-class functions, 42
first-class objects, 42
flags, common API, 541
flags, unit, 398400
FlagTutorial, 637
flight functions, 1105
FlipCameraYaw, 637638
floating-point numbers, 2223
floor, Lua API, 1003
focus (U) attributes,
SecureActionButtonTemplate, 293
FocusUnit, 638
folders, addon, 125131
FollowUnit, 638
font definitions
altering, 178179
FontStrings, 165
overview of, 177178
Font objects, 12211222
<FontHeight> element, FontString, 165
FontInstance type, reference guide, 11311135
fontObject attribute, dropdown menus, 438
FontStrings
adding text to frame, 164166
addons and, 139
creating and updating status text, 223224
creating templates, 173
defining CombatTracker’s frame, 272
grouping into graphical layers, 152153
parenting, 145146
reference guide, 11351138
for statement, 4851, 84. See also generic for
loops
forceinsecure, Lua API, 1003
ForceQuit, 638
format, Lua API, 1003
formats
GUIDs, 397
new strings, 9596
forums, for addon authors, 13491351
forward slash (/), XML, 79
FPS (frames per second), 351
frame handles
additional or changed actions, 479482
allowed actions, 479
overview of, 477479
frame templates, 171186
advantages of, 173174
creating BagBuddy’s item buttons, 174177
defined in UIPanelTemplates.xml, 179180
font definitions, 177179
InputBoxTemplate, 181182
Index FF 1369
TabButtonTemplate, 183
UICheckButtonTemplate, 182
UIPanelButtonTemplate, 180
UIPanelCloseButton, 180
UIPanelScrollBarTemplate, 180
UIRadioButtonTemplate, 183
understanding, 171173
Frame widgets
Button, 11641170
CheckButton, 11701172
ColorSelect, 11721175
Cooldown, 11751176
GameTooltip.See GameTooltip frame type
Minimap, 11921195
Model.See Model frame type
MovieFrame, 12041205
overview of, 11451164
ScrollFrame, 12061208
Frame widgets, methods
AllowAttributeChanges, 1146
CanChangeAttribute, 1146
CreateFontString, 1146
CreateTexture, 1146
CreateTitleRegion, 1147
DisableDrawLayer, 1147
EnableDrawLayer, 1147
EnableJoystick, 1147
EnableKeyboard, 1147
EnableMouse, 1148
EnableMouseWheel, 1148
GetAttribute, 1148
GetBackdrop, 1148
GetBackdropBorderColor,
11481149
GetBackdropColor, 1149
GetBoundsRect, 1149
GetChildren, 11491150
GetClampRectInsets, 1150
GetDepth, 1150
GetEffectiveAlpha, 11501151
GetEffectiveDepth, 1151
GetEffectiveScale, 11511152
GetFrameLevel, 1152
GetFrameStrata, 1152
GetHitRectInsets, 11521153
GetID, 1153
GetMaxResize, 1153
GetMinResize, 1153
GetNumChildren, 1153
GetNumRegions, 1153
GetRegions, 1154
GetScale, 1154
GetTitleRegion, 1154
IgnoreDepth, 1154
IsClampedToScreen, 1154
IsEventRegistered, 11541155
IsIgnoringDepth, 1155
IsJoystickEnabled, 1155
IsKeyboardEnabled, 1155
IsMouseEnabled, 1155
IsMouseWheelEnabled, 1155
IsMovable, 1155
IsResizable, 1156
IsToplevel, 1156
IsUserPlaced, 1156
Lower, 1156
Raise, 1156
RegisterAllEvents, 1156
RegisterEvent, 1156
RegisterForDrag, 1157
SetAttribute, 1157
SetBackdrop, 11571158
SetBackdropBorderColor, 1158
SetBackdropColor, 1158
SetClampedToScreen, 1159
SetClampRectInsects, 11581159
SetDepth, 1160
SetFrameLevel, 1160
SetFrameStrata, 1160
SetHitRectInsets, 1160
SetID, 11601161
SetMaxResize, 1161
SetMinResize, 1161
SetMovable, 1161
SetResizable, 11611162
SetScale, 1162
SetToplevel, 1163
SetUserPlaced, 1163
StartMoving, 1163
StartSizing, 1163
StopMovingOrSizing, 1163
UnregisterAllEvents, 1163
UnregisterEvent, 11631164
frameLevel attribute, 151
framerate, and graphics performance, 351
Frame:RegisterEvent() method, 140
frames, 144150
addons and, 138139
attributes controlling secure, 288
avoiding missing, 1326
Combat Status addon, 410412
CombatTracker addon, 270272
finding existing, 167
handling game events, 139140
layering with levels, 151
layering with strata, 150151
manipulating with handles, 477479
modifying action buttons, 299300
protected, 286288
script wrappers. See wrapping frame scripts
secure. See secure environment
Sliders, 12151218
testing dragging, 279
tooltips for player, 452
1370 Index F–G
frames, creating
adding text using FontStrings, 164166
adding textures to. See textures
anchoring objects to, 147149
BagBuddy design, 153154
dropdown frames, 431, 433
giving sizes to objects, 146147
graphics, 155
layering, 150153
overview of, 144
parenting, 145146
with templates, 176177
using Lua, 149150
frames, creating with group templates
health update events, 513514
moving the header, 512513
name changes, 516
overview of, 501
power update events, 514516
responding to events, 511
SecureGroupHeader.See SecureGroupHeader,
configuring
SquareUnitFrames.See SquareUnitFrames
summary, 526
targetingunitonleftclick,511512
/framestack slash command, 167, 202
frameStrata, 271, 546547
FrameXML, 85, 189, 202
FrameXML_Debug, 638639
frexp, Lua API, 1004
Friz Quadrata font, 177
func attribute, 440
function aliases, added to Lua in WoW, 109110
function hooking
alternatives to, 367
creating function hooks, 369
deciding when to hook, 365367
hooking securely, 364365
hooking widget scripts, 362363
MapZoomOut and, 367372
modifying return values, 360362
overview of, 359
replacing scripts vs., 461462
summary, 370371
understanding, 359360
writing timer code for, 369370
function keyword, 3940
function menu items, dropdown menus, 440
function signatures, 91, 539540
functions. See also iterators
accepting variable number of arguments,
81–82
adding to CombatTracker.lua, 275278
adding to namespace, 6263
arguments and returns, 4142
avoiding creating inside other, 1318
breaking apart long, 1309
caching frequently accessed, 1322
creating, 3940
declaring vararg function, 8283
defined, 39
defining using : operator, 6667
environments, 474
generic for loops and iterators, 8490
given, 1323
hooking, 364
local, 4041
Lua standard libraries. See Lua standard
libraries
as Lua values, 4243
multiple return values, 7780
player information functions, 476
reducing garbage using recursive, 13141317
secure API functions, 475476
select(), 81, 8384
using dummy variable, 80
G
g(green) attribute, ColorPicker, 441
game element tooltips, 455458
game events. See events, responding to
game world, WoW, 3
GameFontNormalSmall font definition, 177178
GameMovieFinished, 640
GameTooltip frame type
overview of, 455458
reference guide, 11761192
as widget type, 229
GameTooltipText frame, 460
garbage
minimizing unnecessary, 13111312
recyclable objects, 13171318
recyclable tables, 13181319
reducing, 13121317
general conditions, secure environment,
493496
generic for loops, 8490
clearing table, 8687
overview of, 84
syntax, 8485
traversing array part of table, 85
traversing entire table, 86
get object method, 6465
GetAbandonQuestItems, 640
GetAbandonQuestName, 640
GetAccountExpansionLevel, 640
GetAchievementCategory, 640641
GetAchievementComparisonInfo, 641
GetAchievementCriteriaInfo, 641642
GetAchievementInfo, 642643
GetAchievementInfoFromCriteria, 643
GetAchievementLink, 643644
GetAchievementNumCriteria, 644
Index GG 1371
GetAchievementNumRewards, 644
GetAchievementReward, 644645
GetActionBarPage, 645
GetActionBarToggles, 645
GetActionCooldown, 645646
GetActionCount, 646
GetActionInfo, 646647
GetActionText, 647648
GetActionTexture, 648
GetActiveLevel, 648
GetActiveTalentGroup, 648
GetActiveTitle, 648649
GetActiveVoiceChannel, 649
GetAddOnCPUUsage, 649
GetAddOnDependencies, 649650
GetAddOnInfo, 650
GetAddOnMemoryUsage, 651
GetAddOnMetadata, 651
GetAlpha(),Font, 1222
GetAlpha(),VisibleRegion, 1129
GetAltArrowKeyMode(),EditBox, 1231
GetAnchorType(),GameTooltip, 11781179
GetAnimationGroups(),Region, 1124
GetAnimations(),AnimationGroup, 1239
GetAreaSpiritHealerTime, 651
GetArenaCurrency, 651
GetArenaTeam, 652653
GetArenaTeamRosterInfo, 653
GetArenaTeamRosterSelection, 653654
GetArmorPenetration, 654
GetAttackPowerForStat, 654
GetAttribute(),Frame, 288, 1148
GetAuctionInvTypes, 654655
GetAuctionItemClasses, 655
GetAuctionItemInfo, 655656
GetAuctionItemLink, 656
GetAuctionItemSubClasses, 656657
GetAuctionItemTimeLeft, 657
GetAuctionSellItemInfo, 657
GetAuctionSort, 657658
GetAutoCompleteResults, 658659
GetAvailableLevel, 659
GetAvailableTitle, 659660
GetBackdrop(),Frame, 1148
GetBackdropBorderColor(),Frame, 11481149
GetBackdropColor(),Frame, 1149
GetBackpackCurrencyInfo, 660
GetBagItemCount function, 1306, 1323
GetBagName, 660
GetBankSlotCost, 661
GetBarberShopStyleInfo, 661
GetBarberShopTotalCost, 661
GetBattlefieldEstimatedWaitTime, 661
GetBattlefieldFlagPosition, 661662
GetBattlefieldInfo, 662
GetBattlefieldInstanceExpiration, 662
GetBattlefieldInstanceInfo, 662663
GetBattlefieldInstanceRunTime, 663
GetBattlefieldMapIconScale, 663
GetBattlefieldPortExpiration, 663664
GetBattlefieldPosition, 664
GetBattlefieldScore, 664665
GetBattlefieldStatData, 665666
GetBattlefieldStatInfo, 666
GetBattlefieldStatus, 666667
GetBattlefieldTeamInfo, 667
GetBattlefieldTimeWaited, 667
GetBattlefieldVehicleInfo, 667668
GetBattlefieldWinner, 668
GetBattlegroundInfo, 668
GetBidderAuctionItems, 668669
GetBillingTimeRested, 669
GetBinding, 669
GetBindingAction, 669670
GetBindingByKey, 670
GetBindingKey, 670
GetBindLocation, 669
GetBlendMode(),Texture, 1139
GetBlinkSpeed(),EditBox, 1231
GetBlockChance, 670
GetBonusBarOffset, 670671
GetBottom(),Region, 11241125
GetBoundsRect(),Frame, 1149
GetBuildInfo, 671
GetButtonState(),Button, 1165
GetBuybackItemInfo, 671
GetBuybackItemLink, 671672
GetCategoryInfo, 674
GetCategoryList, 674
GetCategoryNumAchievements, 674675
GetCenter(), Region, 1125
GetChange(),Alpha, 1254
GetChannelDisplayInfo, 675
GetChannelList, 675
GetChannelName, 675676
GetChannelRosterInfo, 676
GetChatTypeIndex, 676677
GetChatWindowChannels, 677
GetChatWindowInfo, 677
GetChatWindowMessages, 678
GetChecked(),CheckButton, 1171
GetCheckedTexture(),CheckButton, 1171
GetChildren(),Frame, 11491150
GetClampRectInsets(),Frame, 1150
GetClickFrame, 678
GetCoinIcon, 678
GetCoinText, 678679
GetCoinTextureString, 679
GetColorHSV(),ColorSelect, 1172
GetColorRGB(),ColorSelect, 1172
GetColorValueTexture(),ColorSelect, 1173
GetColorValueThumbTexture(),ColorSelect,
1173
GetColorWheelTexture(),ColorSelect, 1173
1372 Index G–G
GetColorWheelThumbTexture(),ColorSelect,
1173
GetCombatRating, 679680
GetCombatRatingBonus, 680681
GetComboPoints, 681
GetCompanionCooldown, 681682
GetCompanionInfo, 682
GetComparisonAchievementPoints, 682
GetComparisonCategoryNumAchievements,
682683
GetComparisonStatistic, 683
GetContainerFreeSlots, 683684
GetContainerItemCooldown, 684
GetContainerItemDurability, 684
GetContainerItemGems, 684685
GetContainerItemID, 685
GetContainerItemInfo, 194, 685
GetContainerItemLink, 685686
GetContainerItemPurchaseInfo, 686
GetContainerItemPurchaseItem, 686687
GetContainerNumFreeSlots, 194, 687
GetContainerNumSlots, 194, 687
GetCorpseMapPosition, 687
GetCorpseRecoveryDelay, 687688
GetCritChance, 688
GetCritChanceFromAgility, 688
GetCurrencyListInfo, 688
GetCurrencyListSize, 689
GetCurrentArenaSeason, 689
GetCurrentBindingSet, 689
GetCurrentGuildBankTab, 689
GetCurrentKeyBoardFocus, 689
GetCurrentLine(),ScrollingMessageFrame,
1226
GetCurrentMapAreaID, 690
GetCurrentMapContinent, 690
GetCurrentMapDungeonLevel, 690
GetCurrentMapZone, 690
GetCurrentResolution, 691
GetCurrentScroll(),ScrollingMessageFrame,
1226
GetCurrentTitle, 691
GetCurrentultisampleFormat, 690691
GetCursorInfo, 691692
GetCursorMoney, 692
GetCursorPosition, 692, 12311232
GetCurve(),Path, 1249
GetCVar, 672
GetCVarAbsoluteMax, 672
GetCVarAbsoluteMin, 672
GetCVarBool, 672673
GetCVarDefault, 673
GetCVarInfo, 673
GetCVarMax, 673
GetCVarMin, 674
GetDailyQuestsCompleted, 692
GetDamageBonusStat, 692
GetDeathReleasePosition, 692693
GetDefaultLanguage, 693
GetDegrees(),Rotation, 1251
GetDepth(),Frame, 1150
GetDisabledCheckedTexture(),CheckButton,
1171
GetDisabledFontObject(),Button, 1165
GetDisabledTexture(),Button, 1165
GetDodgeChance, 693
GetDrawEdge(),Cooldown, 1175
GetDrawLayer(),LayeredRegion, 1130
GetDungeonDifficulty, 693
GetDuration(),Animation, 1243
GetDuration(),AnimationGroup, 12391240
GetEffectiveAlpha() method, Frame,
11501151
GetEffectiveDepth() method, Frame, 1151
GetEffectiveScale() method, Frame,
11511152
GetElapsed(),Animation, 1243
GetEndDelay(),Animation, 1243
GetEquipmentSetInfo, 693
GetEquipmentSetInfoByName, 693694
GetEquipmentSetItemIDs, 694
GetEquipmentSetLocations, 694
geterrorhandler, Lua API, 1004
GetEventCPUUsage, 694
GetExistingLocales, 694
GetExistingSocketInfo, 695
GetExistingSocketLink, 695
GetExpertise, 695
GetExpertisePercent, 695696
GetFacialHairCustomization, 696
GetFacing(),Model, 1196
GetFactionInfo, 696697
GetFadeDuration(),MessageFrame, 1223
GetFadeDuration(),ScrollingMessageFrame,
12261227
GetFading(),MessageFrame, 1223
GetFading(),ScrollingMessageFrame, 1227
getfenv, Lua API, 1004
GetFirstTradeSkill, 697
GetFogColor(), Model, 1196
GetFogFar(),Model, 1196
GetFogNear(),Model, 1196
GetFont(),FontInstance, 11311132
GetFont(),SimpleHTML, 1208
GetFontObject(),FontInstance, 1132
GetFontObject(),SimpleHTML, 1209
GetFontString(),Button, 1166
GetFrameCPUUsage, 697
GetFrameLevel(),Frame, 1152
GetFramerate, 697
GetFramesRegisteredForEvent, 697698
GetFrameStrata(),Frame, 1152
GetFriendInfo, 698
GetFunctionCPUUsage, 698699
Index GG 1373
GetGameTime, 699
GetGamma, 699
getglobal, 109, 10041005
GetGlyphLink, 699
GetGlyphSocketInfo, 700
GetGMTicket, 699
GetGossipActiveQuests, 700
GetGossipAvailableQuests, 700701
GetGossipOptions, 701
GetGossipText, 701
GetGreetingText, 701
GetGroupPreviewTalentPointsSpent, 701702
GetGuildBankCharterCost, 705
GetGuildBankEventInfo, 706
GetGuildBankItemInfo, 702
GetGuildBankItemLink, 702
GetGuildBankMoney, 702703
GetGuildBankMoneyTransaction, 703
GetGuildBankTabCost, 703
GetGuildBankTabInfo, 703704
GetGuildBankTabPermissions, 704
GetGuildBankText, 704
GetGuildBankTransaction, 704705
GetGuildBankWithdrawLimit, 705
GetGuildBankWithdrawMoney, 705
GetGuildInfo, 706
GetGuildInfoText, 706707
GetGuildRosterInfo, 707
GetGuildRosterLastOnline, 707708
GetGuildRosterMOTD, 708
GetGuildRosterSelection, 708
GetGuildRosterShowOffline, 708
GetGuildTabardFileNames, 708709
GetHairCustomization, 709
GetHeight(),Region, 1125
GetHighlightFontObject(),Button, 1166
GetHighlightTexture(),Button, 1166
GetHistoryLines(),EditBox, 1232
GetHitRectInsets() Frame, 11521153
GetHonorCurrency, 709
GetHorizontalScroll(),ScrollFrame, 1206
GetHorizontalScrollRange(),ScrollFrame,
1206
GetHyperlinkFormat(),SimpleHTML, 1209
GetHyperlinksEnabled(),
ScrollingMessageFrame, 1227
GetHyperlinksEnabled(), SimpleHTML, 1209
GetID(),Frame, 1153
GetIgnoreName, 709
GetInboxHeaderInfo, 709710
GetInboxInvoiceInfo, 710711
GetInboxItem, 711
GetInboxItemLink, 711
GetInboxNumItems, 711
GetInboxText, 711712
GetIndentedWordWrap(),EditBox, 1232
GetIndentedWordWrap(),MessageFrame,
12231224
GetIndentedWordWrap(),
ScrollingMessageFrame, 1227
GetIndentedWordWrap(), SimpleHTML, 1209
GetInitialOffset(),AnimationGroup, 1240
GetInputLanguage(),EditBox, 1232
GetInsertMode(),MessageFrame, 1224
GetInsertMode(),ScrollingMessageFrame,
1227
GetInspectArenaTeamData, 712713
GetInspectHonorData, 713
GetInstanceBootTimeRemaining, 713
GetInstanceDifficulty, 713714
GetInstanceInfo, 714
GetInstanceLockTimeRemaining, 714
GetInventoryAlertStatus, 714715
GetInventoryItemBroken, 715
GetInventoryItemCooldown, 715
GetInventoryItemCount, 716
GetInventoryItemDurability, 716
GetInventoryItemGems, 716
GetInventoryItemID, 717
GetInventoryItemLink, 717
GetInventoryItemQuality, 717
GetInventoryItemsForSlot, 718
GetInventoryItemTexture, 717
GetInventorySlotInfo, 718719
GetItem(),GameTooltip, 1179
GetItemCooldown, 719
GetItemCount, 719720
GetItemFamily, 720721
GetItemGem, 721
GetItemIcon, 721
GetItemInfo, 197, 721722
GetItemQualityColor, 200, 722
GetItemSpell, 723
GetItemStatDelta, 723724
GetItemStats, 724725
GetItemUniqueness, 725
GetJustifyH(),FontInstance, 1132
GetJustifyH(),SimpleHTML, 12091210
GetJustifyV(),FontInstance, 1132
GetJustifyV(),SimpleHTML, 1210
GetKnownSlotFromHighestRankSlot, 725726
GetLanguageByIndex, 729
GetLatestCompletedAchievements, 729730
GetLatestThreeSenders, 730
GetLeft(),Region, 1125
GetLFGPartyResults, 726
GetLFGResults, 726728
GetLFGRoles, 728
GetLFGStatusText, 728729
GetLFGTypeEntries, 729
GetLFGTypes, 729
GetLight(), Model, 11961197
GetLocale, 730
1374 Index G–G
GetLookingForGroup, 730731
GetLooping(),AnimationGroup, 1240
GetLoopState(),AnimationGroup, 1240
GetLootMethod, 731
GetLootRollItemInfo, 732
GetLootRollItemLink, 732
GetLootRollTimeLeft, 732
GetLootSlotInfo, 732733
GetLootSlotLink, 733
GetLootThreshold, 733
GetLowerBackgroundFileName(),
TabardModel, 1203
GetLowerEmblemFileName(),TabardModel,
1203
GetLowerEmblemTexture(),TabardModel, 1204
GetMacroBody, 733
GetMacroIconInfo, 733
GetMacroIndexByName, 734
GetMacroInfo, 734
GetMacroItem, 734
GetMacroItemIconInfo, 734735
GetManaRegen, 735
GetMapContinents, 735
GetMapInfo, 736
GetMapLandmarkInfo, 736737
GetMapOverlayInfo, 737
GetMapZones, 737
GetMasterLootCandidate, 737738
GetMaxArenaCurrency, 738
GetMaxBytes(),EditBox, 1232
GetMaxCombatRatingBonus, 738739
GetMaxDailyQuests, 739
GetMaxFramerate(),Animation, 12431244
GetMaxLetters(),EditBox, 1232
GetMaxLines(),ScrollingMessageFrame, 1227
GetMaxOrder(),AnimationGroup, 12401241
GetMaxOrder(),Path, 12491250
GetMaxResize() method, Frame, 1153
GetMerchantCostItem, 740
GetMerchantItemCostInfo, 739740
GetMerchantItemInfo, 740
GetMerchantItemLink, 740741
GetMerchantItemMaxStack, 741
GetMerchantNumItems, 741
getmetatable, Lua API, 1005
GetMinimapZoneText, 741
GetMinimumWidth() method, GameTooltip, 1179
GetMinMaxValues(),Slider, 1216
GetMinMaxValues(),StatusBar, 1219
GetMinResize() method, Frame, 1153
GetMirrorTimerInfo, 741742
GetMirrorTimerProgress, 742
GetModel() method, Model, 1197
GetModelScale() method, Model, 1197
GetModifiedClick, 742
GetModifiedClickAction, 742
GetMoney, 743
GetMouseButtonClicked, 743
GetMouseButtonName, 743
GetMouseFocus, 743744
GetMovieResolution, 744
GetMultilineIndent(),Font, 1222
GetMultiplesampleFormats, 744
GetMuteName, 744
GetMuteStatus, 745
GetName() method, UIObject, 1121
GetNetStats, 745
GetNewSocketInfo, 745
GetNewSocketLink, 745746
GetNextAchievement, 746
GetNextStableSlotCost, 746
GetNonBlocking() method, Texture, 1139
GetNormalFontObject() method, Button, 1166
GetNormalTexture() method, Button, 1166
GetNumActiveQuests, 746
GetNumAddOns, 746
GetNumArenaOpponents, 747
GetNumArenaTeamMembers, 747
GetNumAuctionItems, 747
GetNumAvailableQuests, 747
GetNumBankSlots, 747748
GetNumBattlefieldFlagPositions, 748
GetNumBattlefieldPositions, 748
GetNumBattlefields, 749
GetNumBattlefieldScores, 748
GetNumBattlefieldStats, 748
GetNumBattlefieldVehicles, 748
GetNumBattlegroundTypes, 749
GetNumber(),EditBox, 1233
GetNumBindings, 749
GetNumBuybackItems, 749
GetNumChannelMembers, 749
GetNumChildren(),Frame, 1153
GetNumCompanions, 750
GetNumComparisonCompletedAchievements,
750
GetNumCompletedAchievements, 750
GetNumDeclensionSets, 750
GetNumDisplayChannels, 751
GetNumDungeonMapLevels, 751
GetNumEquipmentSets, 751
GetNumFactions, 751
GetNumFrames, 751
GetNumFriends, 752
GetNumGossipActiveQuests, 752
GetNumGossipAvailableQuests, 752
GetNumGossipOptions, 752
GetNumGuildBankMoneyTransactions, 752
GetNumGuildBankTabs, 752753
GetNumGuildBankTransactions, 753
GetNumGuildEvents, 753
GetNumGuildMembers, 753
GetNumIgnores, 753
GetNumLanguages, 754
Index GG 1375
GetNumLetters(),EditBox, 12321233
GetNumLFGResults, 753754
GetNumLinesDisplayed(),
ScrollingMessageFrame, 12271228
GetNumLootItems, 754
GetNumMacroIcons, 754
GetNumMacroItemIcons, 754
GetNumMacros, 754
GetNumMapLandmarks, 754755
GetNumMapOverlays, 755
GetNumMessages(),ScrollingMessageFrame,
1228
GetNumModifiedClickActions, 755
GetNumMutes, 755
GetNumPartyMembers, 278, 755
GetNumPetitionNames, 755756
GetNumPoints(),Region, 1125
GetNumQuestItems, 756
GetNumQuestLeaderBoards, 756
GetNumQuestLogChoices, 756
GetNumQuestLogEntries, 756
GetNumQuestLogRewards, 757
GetNumQuestRewards, 757
GetNumQuestWatches, 757
GetNumRaidMembers, 757
GetNumRegions(), Frame, 1153
GetNumRoutes, 757
GetNumSavedInstances, 758
GetNumShapeshiftForms, 758
GetNumSkillLines, 758
GetNumSockets, 758
GetNumSpellTabs, 758
GetNumStablePets, 759
GetNumStableSlots, 759
GetNumTalentGroups, 759
GetNumTalents, 759760
GetNumTalentTabs, 759
GetNumTitles, 760
GetNumTrackedAchievements, 760
GetNumTrackingTypes, 760
GetNumTradeSkills, 760
GetNumTrainerServices, 760761
GetNumVoiceSessionMembersBySessionID, 761
GetNumVoiceSessions, 761
GetNumWhoResults, 761
GetNumWorldStateUI, 761
GetObjectiveText, 761762
GetObjectType(), UIObject, 11211122
GetOffset(),ControlPoint, 1250
GetOffset(),Translation, 1254
GetOptOutOfLoot, 762
GetOrder(),Animation, 1244
GetOrder(),ControlPoint, 1250
GetOrientation(),Slider, 1216
GetOrientation(),StatusBar, 1219
GetOrigin(),Rotation, 1251
GetOrigin(),Scale, 12521253
GetOwner(),GameTooltip, 1179
GetOwnerAuctionItems, 762
GetPadding(),GameTooltip, 1179
GetParent(),ParentedObject, 1122
GetParryChance, 763764
GetPartyAssignment, 764
GetPartyLeaderIndex, 764
GetPartyMember, 764
GetPetActionCooldown, 764765
GetPetActionInfo, 765
GetPetActionSlotUsable, 765
GetPetActionsUsable, 765766
GetPetExperience, 766
GetPetFoodTypes, 766
GetPetHappiness, 766
GetPetIcon, 766
GetPetitionInfo, 767
GetPetitionItemInfo, 767768
GetPetitionNameInfo, 768
GetPetTalentTree, 767
GetPetTimeRemaining, 767
GetPingPosition(),Minimap, 1192
GetPlayerFacing, 768
GetPlayerInfoByGUID, 768
GetPlayerMapPosition, 769
GetPlayerTradeMoney, 769
GetPoint(),Region, 11251126
GetPosition(),Model, 11971198
GetPossessInfo, 769
GetPowerRegen, 769770
GetPreviousAchievement, 770
GetPreviousArenaSeason, 770
GetProgress(),Animation, 1244
GetProgress(),AnimationGroup, 1241
GetProgressText, 770
GetProgressWithDelay(),Animation, 1244
GetPushedTextOffset(),Button, 1166
GetPushedTexture(),Button, 11661167
GetPVPDesired, 762
GetPVPLifetimeStats, 762
GetPVPRankInfo, 763
GetPVPSessionStats, 763
GetPVPTimer, 763
GetPVPYesterdayStats, 763
GetQuestBackgroundMaterial, 770771
GetQuestDifficultyColor, 771
GetQuestGreenRange, 771772
GetQuestIndexForTimer, 772
GetQuestIndexForWatch, 772
GetQuestItemInfo, 772773
GetQuestItemLink, 773
GetQuestLink, 773
GetQuestLogChoiceInfo, 774
GetQuestLogGroupNum, 774
GetQuestLogItemLink, 774
1376 Index G–G
GetQuestLogLeaderBoard, 774775
GetQuestLogPushable, 775
GetQuestLogQuestText, 775
GetQuestLogRequiredMoney, 775
GetQuestLogRewardHonor, 775
GetQuestLogRewardInfo, 775776
GetQuestLogRewardMoney, 776
GetQuestLogRewardSpell, 776
GetQuestLogRewardTalents, 776
GetQuestLogRewardTtitle, 777
GetQuestLogSelection, 777
GetQuestLogSpecialItemCooldown, 777
GetQuestLogSpecialItemInfo, 777778
GetQuestLogSpellLink, 778
GetQuestLogTimeLeft, 778
GetQuestLogTitle, 778779
GetQuestMoneyToGet, 779
GetQuestResetTime, 779
GetQuestReward, 779
GetQuestSpellLink, 779780
GetQuestText, 780
GetQuestTimers, 780
GetRadians(),Rotation, 12511252
GetRaidRosterInfo, 780781
GetRaidRosterSelection, 781
GetRaidTargetIndex, 781
GetRangedCritChance, 781
GetReadyCheckStatus, 781782
GetReadyCheckTimeLeft, 782
GetRealmName, 783
GetRealNumPartyMembers, 782
GetRealNumRaidMembers, 782
GetRealZoneText, 782
GetRect(),Region, 1126
GetRefreshRates, 783
GetRegionParent(),Animation, 1244
GetRegions(),Frame, 1154
GetReleaseTimeRemaining, 783
GetRepairAllCost, 783
GetResSicknessDuration, 783
GetRestState, 784
GetReverse(),Cooldown, 1175
GetRewardHonor, 784
GetRewardMoney, 784
GetRewardSpell, 784785
GetRewardTalents, 785
GetRewardText, 785
GetRewardTitle, 785
GetRight(),Region, 1126
GetRotatesTexture(),StatusBar, 1219
GetRuneCooldown, 785786
GetRuneCount, 786
GetRuneType, 786787
GetRunningMacro, 787
GetRunningMacroButton, 787
GetSavedInstanceInfo, 787788
GetScale(),Frame, 1154
GetScale(),Scale, 1253
GetScreenHeight, 788
GetScreenResolutions, 788
GetScreenWidth, 788
GetScript, 363, 11221123
GetScriptCPUUsage, 788789
GetScrollChild(),ScrollFrame, 12061207
GetSelectedAuctionItem, 789
GetSelectedBattlefield, 789
GetSelectedDisplayChannel, 789
GetSelectedFaction, 789
GetSelectedFriend, 790
GetSelectedIgnore, 790
GetSelectedMute, 790
GetSelectedSkill, 790
GetSelectedStablePet, 790791
GetSendMailCOD, 791
GetSendMailItem, 791
GetSendMailItemLink, 791
GetSendMailMoney, 791792
GetSendMailPrice, 792
GetShadowColor(),FontInstance, 11321133
GetShadowColor(),SimpleHTML, 1210
GetShadowOffset(),FontInstance, 1133
GetShadowOffset(),SimpleHTML, 12101211
GetShapeshiftForm, 792
GetShapeshiftFormCooldown, 792
GetShapeshiftFormInfo, 792793
GetShieldBlock, 793
GetSkillLineInfo, 793
GetSmoothing(),Animation, 1245
GetSmoothProgress(),Animation, 12441245
GetSocketItemBoundTradeable, 793794
GetSocketItemInfo, 794
GetSocketItemRefundable, 794
GetSocketTypes, 794795
GetSpacing(),FontInstance, 1133
GetSpacing(),SimpleHTML, 1211
GetSpell(),GameTooltip, 1180
GetSpellAutocast, 795
GetSpellBonusDamage, 795
GetSpellBonusHealing, 795
GetSpellCooldown, 796
GetSpellCount, 796797
GetSpellCritChance, 797
GetSpellCritChanceFromIntellect, 797
GetSpellInfo, 797798
GetSpellLink, 798
GetSpellName, 798799
GetSpellPenetration, 799
GetSpellTabInfo, 799
GetSpellTexture, 799800
GetStablePetFoodTypes, 800
GetStablePetInfo, 800
GetStartDelay(),Animation, 1245
GetStatistic, 800
GetStatisticsCategoryList, 801
Index GG 1377
GetStatusBarColor(),StatusBar, 12191220
GetStatusBarTexture(),StatusBar, 1220
GetStringHeight(),FontString, 1136
GetStringWidth(),FontString, 11361137
GetSubZoneText, 801
GetSuggestedGroupNum, 801
GetSummonConfirmAreaName, 801
GetSummonConfirmSummoner, 801802
GetSummonConfirmTimeLeft, 802
GetSummonFriendCooldown, 802
GetTabardCreationCost, 802
GetTable, 1319
GetTalentInfo, 802803
GetTalentLink, 803
GetTalentPrereqs, 803804
GetTalentTabInfo, 804805
GetTargetTradeMoney, 805
GetTaxiBenchmarkMode, 805
GetTerrainMip, 805
GetTexCoord(),Texture, 11391140
GetTexCoordModifiesRect(),Texture, 1140
GetText
Button, 1167
EditBox, 1233
filtering by name, 226
FontString, 1137
reference guide, 805806
GetTextColor() method, FontInstance, 1133
GetTextColor() method, SimpleHTML, 1211
GetTextHeight() method, Button, 1167
GetTextInsets(),EditBox, 1233
GetTexture(),Texture, 1140
GetTextWidth (),Button, 1167
GetThreatStatusColor, 806
GetThumbTexture(),Slider, 1216
GetTime, 276, 806
GetTimeVisible(),MessageFrame, 1224
GetTimeVisible(),ScrollingMessageFrame,
1228
GetTitleName, 806807
GetTitleRegion(),Frame, 1154
GetTitleText, 807
GetTop(),Region, 1126
GetTotalAchievementPoints, 807
GetTotemInfo, 807
GetTotemTimeLeft, 807808
GetTrackedAchievements, 808
GetTrackingInfo, 808
GetTrackingTexture, 808
GetTradePlayerItemInfo, 809
GetTradePlayerItemLink, 809
GetTradeSkillCooldown, 809
GetTradeSkillDescription, 810
GetTradeSkillIcon, 810
GetTradeSkillInfo, 810811
GetTradeSkillInvSlotFilter, 811
GetTradeSkillInvSlots, 811
GetTradeSkillItemLevelFilter, 811
GetTradeSkillItemLink, 812
GetTradeSkillLine, 812
GetTradeSkillListLink, 812
GetTradeSkillNumMade, 812813
GetTradeSkillNumReagents, 813
GetTradeSkillReagentInfo, 813814
GetTradeSkillReagentItemLink, 814
GetTradeSkillRecipleLink, 814
GetTradeskillRepeatCount, 816
GetTradeSkillSelectionIndex, 814815
GetTradeSkillSubclasses, 815
GetTradeSkillSubclassFilter, 815
GetTradeSkillTools, 815
GetTradeTargetItemInfo, 815816
GetTradeTargetItemLink, 816
GetTrainerGreetingText, 816
GetTrainerSelectionIndex, 816817
GetTrainerServiceAbilityReq, 817
GetTrainerServiceCost, 817
GetTrainerServiceDescription, 817
GetTrainerServiceIcon, 818
GetTrainerServiceInfo, 818
GetTrainerServiceItemLink, 818
GetTrainerServiceLevelReq, 818819
GetTrainerServiceNumAbilityReq, 819
GetTrainerServiceSkillLine, 819820
GetTrainerServiceSkillReq, 820
GetTrainerServiceTypeFilter, 820
GetTrainerSkillLineFilter, 820821
GetTrainerSkillLines, 821
GetUnit(),GameTooltip, 1180
GetUnitHealthModifier, 821
GetUnitHealthRegenRateFromSpirit, 821
GetUnitManaRegenRateFromSpirit, 821822
GetUnitMaxHealthModifier, 822
GetUnitName, 822, 1323
GetUnitPitch, 822
GetUnitPowerModifier, 822823
GetUnitSpeed, 823
GetUnspentTalentPoints, 823
GetUpperBackgroundFileName(),
TabardModel, 1204
GetUpperEmblemFileName(),TabardModel,
1204
GetUpperEmblemTexture(),TabardModel, 1204
GetUTF8CursorPosition(),EditBox, 1233
GetValue(),Slider, 1216
GetValue(),StatusBar, 1220
GetValueStep(),Slider, 1217
GetVertexColor(),Texture, 1140
GetVerticalScroll(),ScrollFrame, 1207
GetVerticalScrollRange(),ScrollFrame,
1207
GetVideoCaps, 823824
GetVoiceCurrentSessionID, 824
1378 Index G–G
GetVoiceSessionInfo, 824
GetVoiceSessionMembershipInfoBySessionID,
824
GetVoiceStatus, 825
GetWatchedFactionInfo, 825
GetWeaponEnchantInfo, 825826
GetWhoInfo, 826
GetWidth(),Region, 1126
GetWintergraspWaitTime, 826
GetWorldPVPQueueStatus, 826827
GetWorldStateUIInfo, 827828
GetXPExhaustion, 828
GetZonePVPInfo, 828829
GetZoneText, 829
GetZoom(),Minimap, 1192
GetZoomLevels(),Minimap, 1193
GIMP (GNU Image Manipulation Program),
374375
Git, 13441347
git commit command, 1346
git init command, 13451346
git status command, 1346
GiveMasterLoot, 829
global aliases, added to Lua, 109110
global environments, private, 474475
global strings, localizing with, 461, 13231324
global tables, localizing with, 136137
global variables
COMBATLOG_OBJECT_TYPE, 398
creating slash commands and, 337338
defined, 35
global widget handler arguments,
13241325
local variables vs., 13101311
scope, 35–37
GlobalStrings.lua, 13231324
Glyph functions, 10541055
glyphIndex, API meta-type, 547
GlyphMatchesSocket, 829
GM survey functions, 1054
GM ticket functions, 1054
gmatch, Lua API, 1005
GMResponseNeedMoreHelp, 639
GMResponseResolve, 639
GMSurveyAnswer, 639
GMSurveyAnswerSubmit, 639
GMSurveyCommentSubmit, 639
GMSurveyQuestion, 639
GMSurveySubmit, 640
GNU Image Manipulation Program (GIMP),
374375
Google Code, hosting, 13531354
‘‘gossip’’ dialog functions, NPC, 10801081
gradients, coloring textures with, 159160
GradientType, 84–85
GrantLevel, 829
graphic files, 133134
graphic updates
delaying using OnUpdate, 352353
grouping events to avoid over-processing,
354355
grouping multiple events, 355356
and OnUpdate, 356357
overview of, 351
subpatterns and, 357
graphical components
adding with Adobe Photoshop, 377
adding with GIMP, 375
adding with Paint Shop Pro, 380
layers, textures and font strings, 152153
graphics. See also Photoshop; textures
finding frame, 155
layering frames, 150153
showing with textures, 139
graphics, custom
with Adobe Photoshop, 376378
with GIMP, 374375
overview of, 373
with Paint Shop Pro, 380382
rules for, 373374
summary, 385
testing new textures, 383385
greater than (¿) operator, strings, 27
green (g) attribute, ColorPicker, 441
Green box, 384
greeting(), 45–46
group functions, 10681069
group headers. See SecureGroupHeader,
configuring
group templates, frames. See frames, creating
with group templates
grouping attributes, secure group headers,
503504
groups
events to avoid over-processing, 354355
multiple events, 355356
gsub, Lua API, 1006
GUIDs (globally unique Identifiers)
API meta-type, 547549
overview of, 396397
for units, 509
guild bank functions, 10551056
guild functions, 10561059
GuildControlAddRank, 829830
GuildControlDelRank, 830
GuildControlGetNumRanks, 830
GuildControlGetRankFlags, 830
GuildControlGetRankName, 830
GuildControlSaveRank, 831
GuildControlSetRank, 831
GuildControlSetRankFlag, 831
GuildDemote, 831
GuildDisband, 831
GuildInfo, 832
Index GI 1379
GuildInvite, 832
GuildLeave, 832
GuildPromote, 832
GuildRoster, 832
GuildRosterSetOfficerNote, 832
GuildRosterSetPublicNote, 832
GuildSetLeader, 833
GuildSetMOTD, 833
GuildUninvite, 833
H
handler functions, 337338
harmbutton, 298
harmful spells, casting, 290291, 298
HasAction, 833
hasColorSwatch attribute, ColorPicker, 441
HasFilledPetition, 833834
HasFocus(),EditBox, 12331234
HasFullControl, 834
HasInspectHonorData, 834
HasKey, 834
HasNewMail, 834
hasOpacity attribute, ColorPicker, 441
HasPetSpells, 834
HasPetUI, 835
HasScript(), Object, 1123
HasSoulstone, 835
HasWandEquipped, 835
headers
creating template for, 508509
moving, 512513
SecureGroupHeader.See SecureGroupHeader,
configuring
HEAL, combat events, 392
health update events, 513514
HearthAndResurrectFromArea, 835
help, asking for, 203
helpbutton, 298
hexadecimal notation
converting to RGB values, 7778
Lua converting numbers to, 2122
hg commit command, 1347
hg init command, 1347
hg pull command, 1348
hg push command, 1347
hg status command, 1347
Hide() method, VisibleRegion, 1129
HideRepairCursor, 835
hiding objects, 166
highlighting units, on mouseover, 516517
HighlightText(),EditBox, 1234
history
making changes in Lua interpreter using, 19
tracking. See version control systems
hook chains, 365366
hooking, function, 362365
HookScript() method, ScriptObject, 1123
hooksecurefunc function, 364365, 10061007
hosting
Google Code, 13531354
personal web, 1355
Sourceforge, 13541355
WOW-specific, 13521353
HTML, and XML, 112
hyperlink, API meta-type, 549552
hyperlinks, 196197, 10591060
I
I18n, 134
identifier, variable, 25
if statement
complex expressions, 44
decision-making with, 43
displaying personalized greeting, 4546
extended conditionals, 4445
simple conditionals, 4344
if...elseif statements
checking expected conditions first, 13191320
exploiting shortcut evaluation, 13201322
as extended conditionals, 4445
IgnoreDepth() method, Frame, 1154
images
creating with Adobe Photoshop, 376377
creating with GIMP, 374375
creating with Paint Shop Pro, 380
saving in Adobe Photoshop, 378379
saving in Paint Shop Pro, 382
InboxItemCanDelete, 836
inc object method, 6465
IncGamers, 1351, 1353
InCinematic, 835
InCombatLockdown() function, 277, 835836
incompatible state, game version, 126127
__index metamethod, 7276
indexing tables, 5455
information
adding to tooltips, 458459
getting from tooltips, 460
player functions, 476
in-game movie playback functions, 1060
inheritance of attributes, 296
Initialize(), CombatStatus addon, 402404
InitializeTabardColors() method,
TabardModel, 1204
initializing, dropdown menus, 433434
InitiateTrade, 836
InputBoxTemplate template, 181182
inputs, debugstack, 109
InRepairMode, 836
Insert(),EditBox, 1234
Insignia of the Alliance, numeric item IDs, 195
inspect functions, 10601061
1380 Index I–I
INSTAKILL, combat events, 393
instance functions, 1061
InteractUnit, 836
## Interface: directive, addons, 126127
interface number, 127
InterfaceOptions_AddCategory, 837
InterfaceOptionsFrame_OpenToCategory, 837
Internet Relay Chat (IRC), 13511352
INTERRUPT, combat events, 393
inventory
displaying player, 198200
filtering by name, 224227
functions, 10611062
testing update function, 200201
tracking changes to, 246251
using items from, 253254
inventoryID, API meta-type, 552
InviteUnit, 837
ipairs() function, 8586, 10071008
IRC (Internet Relay Chat), 13511352
IsActionInRange, 837838
IsActiveBattlefieldArena, 838
IsActiveQuestTrivial, 838
IsAddOnLoaded, 838839
IsAddOnLoadOnDemand, 838
IsAltKeyDown, 839
IsArenaTeamCaptain, 839
IsAtStableMaster, 839
IsAttackAction, 839840
IsAttackSpell, 840
IsAutoFocus(),EditBox, 1234
IsAutoRepeatAction, 840
IsAutoRepeatSpell, 840
IsAvailableQuestTrivial, 831841
IsBattlefiedArena, 841
IsClampedToScreen(),Frame, 1154
IsConsumableAction, 841
IsConsumableItem, 841842
IsConsumableSpell, 842
IsControlKeyDown, 842
IsCurrentAction, 842
IsCurrentItem, 842843
IsCurrentQuestFailed, 843
IsCurrentSpell, 843
IsDelaying(),Animation, 1245
IsDesaturated(),Texture, 1140
IsDesaturateSupported, 843
IsDisplayChannelModerator, 843
IsDisplayChannelOwner, 843
IsDone(),Animation, 1245
IsDone(),AnimationGroup, 1241
IsDragging(),Region, 11261127
IsDressableItem, 844
IsEnabled(),Button, 1167
IsEnabled(),Slider, 1217
IsEquippableItem, 844
IsEquippedAction, 844
IsEquippedItem, 844845, 1180
IsEquippedItemType, 845
IsEventRegistered() method, Frame,
11541155
IsFactionInactive, 846
IsFalling, 846
IsFishingLoot, 846
IsFlyableArea, 846
IsFlying, 846
IsGuildLeader, 846
IsHarmfulItem, 846
IsHarmfulSpell, 846847
IsHelpfulItem, 848
IsHelpfulSpell, 848
IsIgnored, 848
IsIgnoredOrMuted, 848849
IsIgnoringDepth(),Frame, 1155
IsInArenaTeam, 849
IsIndoors, 849
IsInGuild, 849
IsInInstance, 849
IsInLFGQueue, 849
IsInMECompositionMode(),EditBox, 1234
IsInventoryItemLocked, 850
IsItemInRange, 850
IsJoystickEnabled(),Frame, 1155
IsKeyboardEnabled(),Frame, 1155
IsLeftAltKeyDown, 850
IsLeftControlKeyDown, 850
IsLeftShiftKeyDown, 851
IsLinuxClient, 851
IsLoggedIn, 851
IsMacClient, 851
IsModifiedClick, 851852
IsModifierKeyDown, 852
IsMounted, 852
IsMouseButtonDown, 852853
IsMouseEnabled(),Frame, 1155
IsMouseLooking, 853
IsMouseWheelEnabled(),Frame, 1155
IsMovable(),Frame, 1155
IsMultiLine(),EditBox, 12341235
IsMuted, 853
IsNumeric(),EditBox, 1235
IsObjectType(), UIObject, 1122
IsOutdoors, 853854
IsOutOfBounds, 853
IsOwned(),GameTooltip, 1180
IsPartyLeader, 854
IsPassiveSpell, 854855
IsPassword(),EditBox, 1235
IsPaused(),Animation, 12451246
IsPaused(),AnimationGroup, 1241
IsPendingFinish(),AnimationGroup, 1241
IsPetAttackActive, 855
IsPlayerResolutionAvailable, 855
IsPlaying(),Animation, 1246
Index IK 1381
IsPlaying(),AnimationGroup, 1241
IsPossessBarVisible, 855
IsProtected(), 287, 1127
IsPVPTimerRunning, 854
IsQuestCompletable, 855
IsQuestLogSpecialItemInRange, 855856
IsQuestWatched, 856
IsRaidLeader, 856
IsRaidOfficer, 856
IsRealPartyLeader, 856
IsRealRaidLeader, 856
IsReferAFriendLinked, 857
IsResizable(),Frame, 1156
IsResting, 857
IsRightAltKeyDown, 857
IsRightControlKeyDown, 857
IsRightShiftKeyDown, 857
issecure, Lua API, 1008
issecurevariable, Lua API, 1008
IsSelectedSpell, 858
IsShiftKeyDown, 858
IsShown(), 166, 1129
IsSilenced, 858
IsSpellInRange, 858859
IsSpellKnown, 859
IsStackableAction, 859
IsStealthed, 859
IsStereoVideoAvailable, 859860
IsStopped(),Animation, 1246
IsSubZonePVPPOI, 860
IsSwimming, 860
IsThreatWarningEnabled, 860
isTitle, 438
IsTitleKnown, 860861
IsToplevel(),Frame, 1156
IsTrackedAchivement, 861
IsTradeSkillLinked, 861
IsTradeSkillTrainer, 861
IsTrainerServiceSkillStep, 861
IsUnit(),GameTooltip, 1180
IsUnitOnQuest, 861862
IsUsableAction, 862
IsUsableItem, 862
IsUsableSpell, 862863
IsUserPlaced(),Frame, 1156
IsVehicleAimAngleAdjustable, 863
IsVisible(), 166, 1129
IsVoiceChatAllowed, 863
IsVoiceChatAllowedByServer, 863
IsVoiceChatEnabled, 863
IsWindowsClient, 863
IsXPUserDisabled, 863
item (U) attributes,
SecureActionButtonTemplate, 292
item API, 194197, 10631064
‘‘item’’ attribute, 1325
item functions, 295
item hyperlinks, 196197
item information, loading tooltip with, 458459
item target attributes,
SecureActionButtonTemplate, 294
item text functions, 1063
‘‘item’’ type button, 294295
ItemButtonTemplate, 174
ItemHasRange, 864
itemID, API meta-type, 195197, 553
itemLocation, API meta-type, 553556
itemQuality, API meta-type, 553554
itemString, API meta-type, 195196, 554
ItemTextGetCreator, 864
ItemTextGetItem, 864
ItemTextGetMaterial, 864865
ItemTextGetPage, 865
ItemTextGetText, 865
ItemTextHasNextPage, 865
ItemTextNextPage, 866
ItemTextPrevPage, 866
iterators
clearing table, 8687
defined, 84
generic for syntax, 8485
looping through collection, 84
sorting array of table data, 8790
string.gmatch() function, 87
traversing array part of table, 85
traversing entire table, 86
J
JoinBattlefield, 866
JoinPermanentChannel, 866
JoinTemporaryChannel, 866867
JumpOrAscendStart, 867
justifyH, API meta-type, 438, 554
justifyV, API meta-type, 554
K
KBArticle_BeginLoading, 867
KBArticle_GetData, 867
KBArticle_IsLoaded, 867
KBQuery_BeginLoading, 868
KBQuery_GetArticleHeaderCount, 868
KBQuery_GetArticleHeaderData, 868
KBQuery_GetTotalArticleCount, 868
KBQuery_IsLoaded, 868869
KBSetup_BeginLoading, 869
KBSetup_GetArticleHeaderCount, 869
KBSetup_GetArticleHeaderData, 869
KBSetup_GetCategoryCount, 869
KBSetup_GetCategoryData, 869870
KBSetup_GetLanguageCount, 870
KBSetup_GetLanguageData, 870
1382 Index K–L
KBSetup_GetSubCategoryCount, 870
KBSetup_GetSubCategoryData, 870
KBSetup_GetTotalArticleCount, 870
KBSetup_IsLoaded, 871
KBSystem_GetMOTD, 871
KBSystem_GetServerNotice, 871
KBSystem_GetServerStatus, 871
keepShownOnClick attribute, function menu, 440
key binding, 309335
binding keys to actions, 314324
code, 330335
creating own binding actions, 312314
defining bindings in XML, 310312
functions, 1065
overview of, 309310
to secure actions, 327329
working with existing bindings, 324327
keyboard functions, 10651066. See also key
binding
KeyRingButtonIDToInvSlotID, 871
Knowledge-base functions, 10661067
L
L10n, 134
LaTEX markup language, 78
layer, API meta-type, 554
LayeredRegion widget type, 11301131
layering, frames and graphics, 150153
layout, Subversion repository, 13401341
ldexp, Lua API, 1008
LearnPreviewTalents, 872
LearnTalent, 872
LeaveBattlefield, 872
LeaveChannelByName, 872
LeaveParty, 872
LEECH, combat events, 392393
length operator (#), 5758
less than (¡) operator, 27
LFGQuery, 871872
LibHealComm library, 1336
libraries. See Lua standard libraries
library-like APIs, 188189
LibSharedMedia library, 13361337
LibStub, 1334
limited play time functions, 1067
ListChannelByName, 873
ListChannels, 873
literals, using named constants vs., 13071308
load on demand (LoD), 127
LoadAddOn, 873874
LoadBindings, 874
loading
addons, 1112, 141142
embedded libraries, 13321333
## LoadManager: directive, addons, 130
## LoadOnDemand: directive, addons, 129
loadstring, Lua API, 10081009
## LoadsWith: directive, addons, 129130
local keyword, 4041
local variables
defined, 35
local functions, 4041
scope and, 35–37
tips for Lua, 13101311
localization
of addons, 127, 134138
encouraging users to contribute, 136
functions for, 137138, 1067
handling partial translation, 138
implementing, 136138
overview of, 134
reasons for, 135
using escape codes, 32
using global strings, 461, 13231324
valid client locales, 135
LockHighlight() method, Button, 1167
LoD (load on demand), 127
log command, 1009, 1343
log10, Lua API, 1009
logging, taint, 303304
LoggingChat, 874
LoggingCombat, 874875
Logout, 875
Logs,FrameXML, 1326
looping, 4851
loot functions
LootSlot, 875876
LootSlotIsCoin, 876
LootSlotIsItem, 876
overview of, 10691070
Lower() method, Frame, 1156
Lua, 1337
boolean values and operators, 3335
creating font strings, 166
creating frames, 149150
defined, 13
downloading and installing, 1415
downloading and installing Lua interpreter,
16–17
Lua interpreter, 1719
numbers, 20–23
scope, 35–37
script files, addons, 133
strings, 2733
texture definitions, 385
using on Web, 15
values and variables, 2327
Lua, best practices
checking expected conditions first, 13191320
minimizing unnecessary garbage, 13111317
recycling objects, 13171318
recycling tables, 13181319
using shortcut evaluation, 13201322
Index LM 1383
Lua interpreter
downloading and installing, 14, 1617
error messages, 18
quitting, 19
running commands, 18
using history to make changes, 19
on Web, 15
Lua standard libraries, 91110
alias functions, 109110
formatting new strings, 9598
functions for, 10701072
math functions, 105108
pattern matching, 98102
pattern matching functions, 102105
string utility functions, 9495
table library, 9294
utility functions, 108109
M
Mac client functions, 10721073
Mac OS X, Lua interpreter for, 1617, 19
macro attributes, 292293
macro functions, 10731074
MacroIconTest, 426429
macroID, API meta-type, 554
mail functions, 10741075
mainassist (U) attribute,
SecureActionButtonTemplate, 293
maintank (U) attribute,
SecureActionButtonTemplate, 293
major versions, embedded libraries, 13321333
many-to-one relationship, 309310
map functions, 10751076
MapZoomOut addon, 367372
master branches, Git repository, 1344
math library functions, 105108
max, Lua API, 1009
media files, addons, 133
memory, table recycling and, 1319
menus. See dropdown menus
merchant functions, 10761077
MerchantFrame_OnShow, 367
Mercurial (hg)
obtaining, 1345
overview of, 1344
terminology, 13441345
typical usage, 13471348
merges, Git and Mercurial, 1344
MessageFrame
ScrollingMessageFrame, 12251230
as widget type, 229, 12221225
metamethods
__concat, 72
__index, 72–74
__newindex, 74–75
__tostring, 71–72
arithmetic, 7071
defining, 69
negation, 71
metatables, 6876
__concat metamethod, 72
__index metamethod, 7274
__newindex metamethod, 7475
__tostring metamethod, 7172
adding, 6869
arithmetic metamethods, 7071
bypassing, 7576
defined, 68
defining metamethods, 69
negation metamethod, 71
Microsoft Visual Studio, 82
Microsoft Windows, Lua interpreter for, 16, 19
Militia Dagger, numeric item ID, 195
min, Lua API, 1009
Minimap frame type, 229230, 11921195
minor versions, embedded libraries, 13321333
MISSED, combat events, 391
mistakes, avoiding common WoW, 13251327
mod, Lua API, 10091010
Model frame type
DressUpModel, 1202
overview of, 11951201
PlayerModel, 12011202
TabardModel, 12021204
as widget type, 230
modified attributes
addons using secure templates, 296297
delegating responsibility, 298
modified click functions, 1078
modifier argument, UNIT_COMBAT event, 269
modifier keys, secure templates, 296297
money functions, 10781079
mouse
buttons, 297298
key binding using. See key binding
scrolling with wheel, 423
MouselookStart, 876
MouselookStop, 876
mouseover, highlighting units on, 516517
movable attribute, CombatTrackerFrame, 271
MoveAndSteerStart, 876
MoveAndSteerStop, 876
MoveBackwardStart, 877
MoveBackwardStop, 877
MoveForwardStart, 877
MoveForwardStop, 877
movement functions, 10791080
MoveViewDownStart, 877
MoveViewDownStop, 877
MoveViewInStart, 877
MoveViewInStop, 877
MoveViewLeftStart, 877
MoveViewLeftStop, 877
1384 Index M–O
MoveViewOutStart, 877
MoveViewOutStop, 877
MoveViewRightStart, 877
MoveViewRightStop, 877
MoveViewUpStart, 877
MoveViewUpStop, 878
MovieFrame type, 12041205
MovieRecording_Cancel, 878
MovieRecording_DataRate, 878
MovieRecording_DeleteMovie, 878
MovieRecording_GetAspectRatio, 878879
MovieRecording_GetMovieFullPath, 879
MovieRecording_GetProgress, 879
MovieRecording_GetTime, 879
MovieRecording_GetViewportWidth, 879
MovieRecording_IsCodecSupported, 880
MovieRecording_IsCompressing, 880
MovieRecording_IsCursorRecording
Supported, 880
MovieRecording_IsRecording, 880
MovieRecording_IsSupported, 880
MovieRecording_MaxLength, 881
MovieRecording_QueueMovieToCompress, 881
MovieRecording_SearchUncompressedMovie,
881
MovieRecording_Toggle, 881
MovieRecording_ToggleGUI, 881
__mul metamethod, 6971
multi-cast action, 1080
multilevel dropdowns, 436437
multiple events, grouping, 355356
multiple return values
overview of, 7781
reducing garbage using, 1312, 1314
multispell attributes,
SecureActionButtonTemplate, 292
music files, 133
MusicPlayer_BackTrack, 882
MusicPlayer_NextTrack, 882
MusicPlayer_PlayPause, 882
MusicPlayer_VolumeDown, 882
MusicPlayer_VolumeUp, 882
N
name attribute, CombatTrackerFrame, 271
name bars, 509511
name filter, adding to inventory, 224227
namespaces, using tables as, 6163
naming conventions
changing names, 516
displaying unit names, 521523
frame template, 173174
named constants vs. literals, 13071308
parenting frames using XML, 145
using consistent style, 1309
variable, 25, 13061307
navigation
minimap used for, 229230
of multiple pages, 219224
negation metamethod, 71
nested loops, variable names in, 1307
NewGMTicket, 882
__newindex metamethod, 7476
newproxy, Lua API, 1010
next() function, 8687, 1010
NextView, 882
nil value, 35, 54, 57
non-root element, well-formed XML, 80
NoPlayTime, 882883
normal APIs, 188
not operator, 3435
notCheckable attribute, 438
notClickable attribute, 438
## Notes: directive, addons, 128
NotifyInspect, 883
NotWhileDeadError, 883
NPC
‘‘gossip’’ dialog functions, 10801081
GUIDs for, 396397
NUM_ACTIONBAR_BUTTONS, 306307
NUM_BAG_SLOTS, 193194, 198
numbers
basic arithmetic operations, 2021
converting strings to, 29
converting to strings, 2829
floating-point, 2223
hexadecimal notation, 2122
scientific notation, 21
numeric item ID, item identifiers, 195196
NumLines() method, GameTooltip, 1180
NumTaxiNodes, 883
O
objective tracking functions, 1081
object-oriented programming, with tables,
63–68
objects
anchoring to frame, 147149
first-class, 42
giving sizes to, 146147
recycling, 13171318
setting parent/child relationship between,
145146
using tables as simple, 6465
visibility, 166
OfferPetition, 883
OffhandHasWeapon, 883
OnAnimFinished widget script, 1255
OnAttributeChanged widget script, 1255
OnChar widget script, 12551256
OnCharComposition widget script, 1256
OnClick handler, 212213, 221, 274
Index OO 1385
OnClick widget script, 12561257
OnColorSelect widget script, 12571258
OnDisable widget script, 1258
OnDoubleClick widget script, 1258
OnDragStart widget script, 274, 12581259
OnDragStop widget script, 274, 12591260
1nil, API meta-types, 542
OnEditFocusGained widget script, 1260
OnEditFocusLost widget script, 1260
124, 1326
OnEnable widget script, 1260
OnEnter widget script, 12601261
OnEnterPressed widget script, 1261
OnEscapePressed widget script, 225, 1261
OnEvent handler, 249250, 274
OnEvent widget script, 244245, 12611262
OnFinished widget script, 1262
OnHide widget script, 1262
OnHorizontalScroll widget script, 1262
OnHyperlinkClick widget script, 12621263
OnHyperlinkEnter widget script, 1263
OnHyperlinkLeave widget script, 12631264
OnInputLanguageChanged widget script,
1264
OnKeyDown widget script, 1264
OnKeyUp widget script, 12641265
OnLeave widget script, 1265
online resources
addon libraries, 13351337
AddonLoader, 130
ArtBrowser, 155
Blizzard interface art, 86
Cogwheel’s Complete Macro Guide, 295
Curseforge, 1345
events, 1277
floating-point numbers, 23
forums, 13491351
Git and Mercurial, 1345
hosting, 13521355
Internet Relay Chat, 13511352
LibStub, 1334
listing API functions by category, 201
Lua interpreter downloads, 16
Lua language, 13
Lua standard libraries, 91
macros, 295
metamethods, 69
rounding number in Lua, 108
Subversion, 1339, 1341
TextBrowser addon, 155
WoW ‘‘Terms of Use’’, 7
x-label directives, 131
XML document validation, 82
XMLValidate utility, 81
OnLoad widget script, 274, 1265
OnLoop widget script, 12651266
OnMessageScrollChanged widget script,
1266
OnMinMaxChanged widget script, 1266
OnMouseDown widget script, 1266
OnMouseUp widget script, 12661267
OnMouseWheel widget script, 1267
OnMovieFinished widget script, 1267
OnMovieHideSubtitle widget script, 1268
OnMovieShowSubtitle widget script, 1268
OnPause widget script, 1268
OnPlay widget script, 1268
OnReceiveDrag widget script, 1268
OnScrollRangeChanged widget script, 1269
OnShow, 367
OnShowChanged widget script, 1269
OnSizeChanged widget script, 12691270
OnSpacePressed widget script, 1270
OnStop widget script, 1270
OnTabPressed widget script, 1270
OnTextChanged widget script, 226, 1270
OnTextSet widget script, 1271
OnTooltipAddMoney widget script, 1271
OnTooltipCleared widget script, 1271
OnTooltipSetAchievement widget script, 1271
OnTooltipSetDefaultAnchor widget script,
1272
OnTooltipSetEquimentSet widget script, 1272
OnTooltipSetFrameStack widget script, 1272
OnTooltipSetItem widget script, 1272
OnTooltipSetQuest widget script, 1272
OnTooltipSetSpell widget script, 1273
OnTooltipSetUnit widget script, 1273
OnUpdate function, Combat Status addon, 408
OnUpdate widget script
delaying updates, 352353
grouping events to avoid over-processing,
354355
grouping multiple events, 355356
overview of, 351352, 1273
performance and, 357
repeating code, 356357
OnUpdateModel widget script, 12731274
OnValueChanged widget script, 1274
OnVerticalScroll widget script, 1274
opacity attribute, ColorPicker, 442
opacityFunc attribute, ColorPicker, 442
opacity/transparency. See alpha channels
open source projects, 1354
OpenCalendar, 883884
OpeningCinematic, 884
## OptionalDeps: directive, addons, 129
or operator, 34, 390
order, of hooks, 366
organization, consistent programming style,
1310
ORIENTATION, XML in WoW, 84
out of date state, game version, 126127
1386 Index P–P
P
PageDown(),ScrollingMessageFrame, 1228
PageUp(),ScrollingMessageFrame, 1228
Paint Shop Pro, 380382
pairs() function, 8687, 10101011
parent attribute, CombatTrackerFrame, 271
$parent string, 173174
ParentedObject type, 1122. See also Region type
parentheses (), 79
parenting, 145146
parentKey attribute, 161, 174
parsing, 341, 343345
PartialPlayTime, 884
party functions, 1082
PARTY_KILL, 396
PARTY_MEMBERS_CHANGED, 409
patch 2.0 security model, 286
Path Animation type, 12481250
Path Animation type, ControlPoint,
12501251
pattern matching
character classes, 98100
defined, 98
example patterns, 102
functions, 102105
pattern anchors, 102
pattern captures, 101
pattern items, 100101
patterns
setting up, 341342
subpatterns and, 342
Pause(),Animation, 1246
Pause(),AnimationGroup, 12411242
pcall, Lua API, 1011
percent sign (%), 98100
PERIODIC_DRAIN, combat events, 393
PERIODIC_ENERGIZE, combat events, 392
PERIODIC_HEAL, combat events, 392
PERIODIC_LEECH, combat events, 392393
PERIODIC_MISSED, combat events, 391
PeriodicTable library, 1336
personal web, hosting, 1355
personalized greetings, 4546
pet functions
overview of, 10831084
PetAbandon, 884
PetAgressiveMode, 884
PetAttack, 884
PetCanBeAbandoned, 884
PetCanBeDismissed, 885
PetCanBeRenamed, 885
PetDefensiveMode, 885
PetDismiss, 885
PetFollow, 885
PetHasActionBar, 885
PetPassiveMode, 885
PetRename, 886
PetStopAttack, 886
PetWait, 886
stable, 1083
petition functions, 1085
pets
GUIDs for, 396397
SquareGroupPetHeaderTemplate, 526
SquareUnitFrames, 523526
updating mappings, 405
Photoshop
adding graphical components, 377
creating alpha channel, 377378
creating new image, 376377
saving images in, 378379
PickupAction, 886
PickupBagFromSlot, 887
PickupCompanion, 887
PickupContainerItem, 887
PickupEquipmentSet, 887
PickupEquipmentSetByName, 888
PickupGuildBankItem, 888
PickupGuildBankMoney, 888
PickupInventoryItem, 888
PickupItem, 889
PickupMacro, 889
PickupMerchantItem, 889
PickupPetAction, 889
PickupPlayerMoney, 890
PickupSpell, 890
PickupStablePet, 890
PickupTradeMoney, 890
PingLocation() method, Minimap,
1193
pipe character (|), 197, 1326
PitchDownStart, 890
PitchDownStop, 891
PitchUpStart, 891
PitchUpStop, 891
PlaceAction, 891
PlaceAuctionBind, 891
PlaceGlyphInSocket, 891892
Play(),Animation, 1246
Play(),AnimationGroup, 1242
PlayCanTeleport, 893
player frame, tooltips, 452
PLAYER_LOGIN, requesting data before,
1327
PLAYER_REGEN_DISABLED event, 268, 277, 409
PLAYER_REGEN_ENABLED event, 268, 277, 410
PlayerIsPVPInactive, 893
PlayerModel frame type, 12011202
players
indicating cross-realm, 1323
information functions, 10851088
showing dead, 519521
PlayMusic, 892
PlaySound, 892
Index PR 1387
PlaySoundFile, 892893
point attribute, 147
populated tables, 5556
Portfolio library, 1336
portrait textures, 160161
pos parameter, table.remove(),60
PostClick widget script, 12741275
post-hooks, 360361, 484485
power update events, 514516
powerType, API meta-type, 554
PreClick widget script, 1275
prefix, modified attributes, 296297
pre-hooks, 360
PreView, 893
primitive types, Lua, 2324
print() function, 278
print() statement, 47
ProcessMapClick, 893
profiling functions, 10511052
programming, best practices, 13061310
breaking apart long functions, 1309
consistent style, 13091310
meaningful variable names, 13061307
named constants instead of literals, 13071308
reworking repetitive code, 13081309
variable naming exceptions, 1307
programming for WoW. See addons; addons,
anatomy of
Programming in Lua (Ierusalimschy), 91
PromoteToAssistant, 893
PromoteToLeader, 894
protected action. See snippets
protected frames, 286288
protected functions, 189190
PurchaseSlot, 894
PutItemInBackpack, 894
PutItemInBag, 894
PvP functions, 10881089
Q
query events, 246
QueryAuctionItems, 894895
QueryGuildBankLog, 895
QueryGuildBankTab, 895896
QueryGuildBankText, 896
QueryGuildEventLog, 896
quest functions, 10891093
Quest Log, 363
QuestChooseRewardError, 896
QuestFlagsPVP, 896
QuestLogPushQuest, 896
QuickCasterButton directory, 300302
Quit, 896897
quoting strings, 2931
R
r(red) attribute, ColorPicker, 441
rad, Lua API, 1011
radio buttons, 183
raid functions, 10941095
Raise() method, Frame, 1156
random, Lua API, 10111012
RandomRoll, 897
RANGE, combat events, 389
rawequal, Lua API, 1012
rawget() function, 7576, 1012
rawset() function, 7576
rawset() function, 1012
readme.txt file, 136
recruit-a-friend functions, 1095
recursive functions, 13141317
recyclable objects, 13171318
red (r) attribute, ColorPicker, 441
RefreshUnit(),PlayerModel, 1201
Region type
FontStrings, 11351138
LayeredRegion, 11301131
overview of, 11241128
VisibleRegion, 11291130
RegisterAllEvents(),Frame, 1156
RegisterCVar, 897
RegisterEvent(), 244, 1156
RegisterForClicks(),Button, 11671168
RegisterForDrag(),Frame, 1157
registration
game event, 140, 244
new saved variable, 252
relative dimensions, sizing objects, 146147
relativePoint attribute, <Anchor> element,
147
relativeTo attribute, <Anchor> element, 147
RELAX NG, XML document validation, 81
release()utility function, 361362
ReloadUI, 897
RemoveChatWindowChannel, 897
RemoveChatWindowMessages, 898
RemoveFriend, 898
RemoveGlyphFromSocket, 898
RemoveQuestWatch, 898
RemoveTrackedAchievement, 898
RenameEquipmentSet, 898
RenamePetition, 899
RepairAllItems, 899
repeat/until loop, 4748
repetitive code, 13081309
ReplaceEnchant, 899
ReplaceIconTexture() method, Model,
1198
ReplaceTradeEnchant, 899
RepopMe, 899
reporting, 278, 279281
ReportPlayerIsPVPAFK, 899
1388 Index R–S
repository
Git and Mercurial, 1344
local Git, 13451346
local Mercurial, 1347
Subversion, 13401341, 1343
RequestBattlefieldPositions, 899
RequestBattlefieldScoreData, 899
RequestBattlegroundInstanceInfo, 900
RequestInspectHonorData, 900
RequestRaidInfo, 900
RequestTimePlayed, 900
## RequiredDeps: directive, addons, 128129
ResetChatColors, 900
ResetChatWindows, 900
ResetCPUUsage, 900
ResetCursor, 900
ResetDisabledAddOns, 901
ResetGroupPreviewTalentPoints, 901
ResetInstances, 901
ResetPreviewTalentPoints, 901
ResetTutorials, 901
ResetView, 902
RespondInstanceLock, 902
RestartGx, 902
RestoreVideoEffectsDefaults, 902
RestoreVideoStereoDefaults, 902
RESURRECT, 393
ResurrectGetOfferer, 902903
ResurrectHasSickness, 903
ResurrectHasTimer, 903
RetrieveCorpse, 903
return listings, API reference, 540541
return statements, 7780
return values, 4142
ReturnInboxItem, 903
RGB, converting hexadecimal values to, 7778
right-click menus, 431
right-click reporting, 279281
rollID, API meta-type, 555
RollOnLoot, 903904
root, modified attributes, 296297
root element, in well-formed XML, 80
Rotation Animation type, 12511252
/run command, execution taint path, 303
RunBinding, 904
RunMacro, 904
RunMacroText, 904
RunScript, 904
S
Save() method, TabardModel, 1204
SaveBindings, 905
## SavedVariables, 130
SavedVariables, 251253
## SavedVariablesPerCharacter, 131
SavedVariablesPerCharacter, 252
SaveEquipmentSet, 905
SaveView, 905
Scale Animation type, 12521253
Schema definition, XML document validation,
81
scientific notation, converting numbers to, 21
scipts. See widget scripts
scope, 35–37
Screenshot, 905
script handlers, CombatTracker, 273274
script wrappers, 485486. See also wrapping
frame scripts
ScriptObject type, 11221123
scripts
hooking securely, 365
hooking widget scripts, 362
replacing instead of hooking, 461462
scroll bars
adding, 417419, 422423
template, 181
scroll child element, adding, 415416
scroll frames, see ScrollFrame
<ScrollChild> element, 415416
ScrollDown(),ScrollingMessageFrame, 1228
ScrollFrame
adding scroll bars, 417419, 422423
adding scroll child element, 415416
code for MacroIconTest, 426429
code for ScrollFrameTest, 424426
creating faux, 419422
manipulating, 416417
overview of, 413414
problems with slider precision, 423424
reference guide, 12061208
scrolling with mouse wheel, 423
summary, 424
using, 414415
as widget type, 231
ScrollingMessageFrame, 231, 12251230
ScrollToBottom(),ScrollingMessageFrame,
1228
ScrollToTop(),ScrollingMessageFrame, 1228
ScrollUp(),ScrollingMessageFrame, 1229
scrub, Lua API, 10121013
SecondsToTime, 905906
secure action. See snippets
secure code
defined, 286
manipulating frames with frame handles,
477479
and protected frames, 286
understanding taint. See taint
secure environment
API functions, 475476
BlessedMenus code, 496499
control object, 476477
frame handles. See frame handles
Index SS 1389
how addon code can be secure, 463464
overview of, 463
post-hook snippet, 484485
preserving state and controlling information,
473474
private global environments, 474475
secure handlers. See secure handlers
summary, 493496
triggered changes. See triggered changes
wrapping frame scripts. See wrapping frame
scripts
writing snippets, 464
secure execution utility functions, 10951096
secure frames. See secure environment
secure handlers
AttributeTemplate, 488490
handler template reference, 466468
integrating click handler with secure action
button, 468473
overview of, 464466
ShowHideTemplate, 487488
secure templates, 285308
applying action buttons in practice, 299302
controlling using attributes, 288
defined, 286
defining behaviors for action buttons, 289295
making simple choices, 296298
necessity of, 285286
protected frames and, 286288
understanding taint. See taint
SecureActionButtonTemplate
attributes controlling behavior of, 291296
creating complex action button, 301302
defining behaviors for action buttons, 289290
how addon code can be secure, 463
integrating click handler with secure action
button, 468473
secure handler template reference, 467468
working with, 289
securecall, Lua API, 1013
SecureCmdOptionParse, 906907
SecureGroupHeader,conguring
display attributes, 504505
filtering attributes, 503
grouping and sorting attributes, 503504
initial configuration function, 505506
options, 502
overview of, 501502
SecureHandlerAttributeTemplate, 488490
SecureHandlerExecute, 464
SecureHandlerShowHideTemplate, 487488
SecureUnitButtonTemplate, 299
select, Lua API, 1013
select() function, 8384
select() statement, 81
SelectActiveQuest, 907
SelectAvailableQuest, 907
SelectGossipActiveQuest, 907
SelectGossipAvailableQuest, 907908
SelectGossipOption, 908
selection, dropdown menus used for, 443445
selection screen, addon, 127
SelectQuestLogEntry, 908
SelectTradeSkill, 908909
SelectTrainerService, 909
self-closing XML tags, 79
SendAddOnMessage, 909910
SendChatMessage, 278, 910911
SendMail, 911
SendWho, 911912
server, API calls communicating with, 246
SetAbandonQuest, 912
SetAchievementComparisonUnit, 912
SetAction(),GameTooltip, 1181
SetActionBarToggles, 912913
SetActiveTalentGroup, 913
SetActiveVoiceChannel, 913
SetActiveVoiceChannelBySessionID, 913
SetAllPoints(), 148, 1127
SetAllPoints XML attribute, 148
SetAlpha(),Font, 1222
SetAlpha(),VisibleRegion, 11291130
SetAlphaGradient(),FontString, 1137
SetAltArrowKeyMode(),EditBox, 1235
SetAnchorType(),GameTooltip, 1181
SetArenaTeamRosterSelection, 913
SetAttribute(),Frame, 288, 367, 1157
SetAuctionItem(),GameTooltip, 1181
SetAuctionSellItem(),GameTooltip, 1181
SetAutoFocus(),EditBox, 1235
SetBackdrop(), 272, 11571158
SetBackdropBorderColor(),Frame, 1158
SetBackdropColor(),Frame, 1158
SetBackpackToken(),GameTooltip, 1182
SetBagItem(),GameTooltip, 1182
SetBagPortraitTexture, 913914
SetBattlefieldScoreFaction, 914
SetBinding, 914
SetBindingClick, 914915
SetBindingItem, 915
SetBindingMacro, 915
SetBindingSpell, 915
SetBlendMode(),Texture, 1141
SetBlinkSpeed(),EditBox, 1235
SetButtonState(),Button, 1168
SetBuybackItem() GameTooltip, 1182
SetCamera(),Model, 1198
SetChange(),Alpha, 12541255
SetChannelOwner, 916
SetChannelPassword, 916
SetChatWindowAlpha, 916
SetChatWindowColor, 916917
SetChatWindowDocked, 917
SetChatWindowLocked, 917
1390 Index S–S
SetChatWindowName, 917
SetChatWindowShown, 917
SetChatWindowSize, 917918
SetChatWindowUninteractable, 918
SetChecked(),CheckButton, 1171
SetCheckedTexture(),CheckButton, 1172
SetClampedToScreen(),Frame, 1159
SetClassBlipTexture(),Minimap, 1193
SetColorHSV(),ColorSelect, 1173
SetColorRGB(),ColorSelect, 1174
SetColorValueTexture(),ColorSelect, 1174
SetColorValueThumbTexture(),ColorSelect,
1174
SetColorWheelTexture(),ColorSelect,
11741175
SetColorWheelThumbTexture(),ColorSelect,
1175
SetCooldown(),Cooldown, 11751176
SetCorpsePOIArrowTexture(),Minimap,
11931194
SetCreature(),PlayerModel, 1201
SetCurrencyBackpack, 918
SetCurrencyToken(),GameTooltip, 1182
SetCurrencyUnused, 918
SetCurrentGuildBankTab, 918
SetCurrentTitle, 919
SetCursor, 919920
SetCursorPosition(),EditBox, 1236
SetCVar, 916
SetDegrees(),Rotation, 1252
SetDepth(),Frame, 1160
SetDesaturated(),Texture, 1141
SetDisabledCheckedTexture(),CheckButton,
1172
SetDisabledFontObject(),Button, 1168
SetDisabledTexture(),Button, 1168
SetDrawEdge(), Cooldown, 1176
SetDrawLayer(),LayeredRegion, 1130
SetDungeonDifficulty, 920
SetDungeonMapLevel, 920
SetDuration(),Animation, 1246
SetEndDelay(),Animation, 1246
SetEquipmentSet(),GameTooltip, 1182
seterrorhandler, Lua API, 1014
SetEuropeanNumbers, 920
SetExistingSocketGem(),GameTooltip,
11821183
SetFacing() method, Model, 1198
SetFactionActive, 920921
SetFactionInactive, 920921
SetFadeDuration(),MessageFrame, 1224
SetFadeDuration(),ScrollingMessageFrame,
1229
SetFading(),MessageFrame, 1224
SetFading(),ScrollingMessageFrame, 1229
setfenv, Lua API, 1014
SetFocus(),EditBox, 1236
SetFogColor(),Model, 11981199
SetFogFar(),Model, 1199
SetFogNear(),Model, 1199
SetFont(),FontInstance, 11331134
SetFont(),SimpleHTML, 1211
SetFontColor(),FontInstance, 1134
SetFontObject(),SimpleHTML, 1212
SetFontString(), Button, 1168
SetFormattedText, 1313
SetFormattedText(),Button, 11681169
SetFormattedText(),FontString, 1137
SetFrameAttributes, 299300
SetFrameLevel(),Frame, 151152, 1160
SetFrameStack() GameTooltip, 1183
SetFrameStrata(),Frame, 151, 1160
SetFriendNotes, 921
SetGamma, 921
setglobal() function, 109, 1014
SetGlow(),Model, 1199
SetGlyph(),GameTooltip, 1183
SetGradient(),Texture, 1142
SetGradientAlpha(),Texture, 1142
SetGuildBankItem(),GameTooltip, 1183
SetGuildBankTabInfo, 921922
SetGuildBankTabPermissions, 922
SetGuildBankTabWithdraw, 922
SetGuildBankText, 922
SetGuildBankWithdrawLimit, 922
SetGuildInfoText, 922923
SetGuildRosterSelection, 923
SetGuildRosterShowOffline, 923
SetHeight(),Region, 1127
SetHighlightFontObject(),Button, 1169
SetHighlightTexture(),Button, 1169
SetHistoryLines(),EditBox, 1236
SetHitRectInsets(),Frame, 1160
SetHorizontalScroll(),ScrollFrame, 1207
SetHyperlink(),GameTooltip, 1183
SetHyperlinkCompareItem(),GameTooltip,
1184
SetHyperlinkFormat(),SimpleHTML, 1212
SetHyperlinksEnabled(),
ScrollingMessageFrame, 1229
SetHyperlinksEnabled(),SimpleHTML, 1212
SetIconTexture(),Minimap, 1194
SetID(),Frame, 11601161
SetInboxItem(),GameTooltip, 1184
SetIndentedWordWrap(),EditBox, 1236
SetIndentedWordWrap(),MessageFrame, 1224
SetIndentedWordWrap(),
ScrollingMessageFrame, 1229
SetIndentedWordWrap(),SimpleHTML,
12121213
SetInitialOffset(),AnimationGroup, 1242
SetInsertMode(),MessageFrame, 1225
SetInsertMode(),ScrollingMessageFrame,
12291230
Index SS 1391
SetInventoryItem(),GameTooltip, 1184
SetInventoryPortraitTexture, 923
SetJustifyH(),FontInstance, 1134
SetJustifyH(),SimpleHTML, 1213
SetJustifyV(),FontInstance, 1134
SetJustifyV(),SimpleHTML, 1213
SetLFGAutojoin, 923
SetLFGComment, 923924
SetLFGRoles, 924
SetLFMAutofill, 924
SetLFMType, 924
SetLight(),Model, 11991200
SetLookingForGroup, 924925
SetLookingForMore, 925
SetLooping(),AnimationGroup, 1242
SetLootItem(),GameTooltip, 1185
SetLootMethod, 925
SetLootPortrait, 925926
SetLootRollItem(),GameTooltip, 1185
SetLootThreshold, 926
SetMacroItem, 926927
SetMacroSpell, 927
SetMapToCurrentZone, 927
SetMapZoom, 927928
SetMaskTexture(),Minimap, 1194
SetMaxBytes(),EditBox, 1236
SetMaxFramerate(),Animation, 1247
SetMaxLetters(),EditBox, 1237
SetMaxLines(),ScrollingMessageFrame, 1230
SetMaxResize(),Frame, 1161
SetMerchantCostItem(),GameTooltip, 1185
SetMerchantItem(),GameTooltip, 1185
setmetatable() function, 6869, 1014
SetMinimumWidth(),GameTooltip, 1185
SetMinMaxValues(),Slider, 1217
SetMinMaxValues(),StatusBar, 1220
SetModel(),Model, 1200
SetModelScale(),Model, 1200
SetModifiedClick, 928
SetMouselookOverrideBinding, 928
SetMovable(),Frame, 1161
SetMultiCastSpell, 929
SetMultiLine(),EditBox, 1237
SetMultilineIndent(),Font, 1222
SetMultilineIndent(),FontString, 11371138
SetMultisampleFormat, 929
SetNextBarberShopStyle, 929
SetNonBlocking(),Texture, 11421143
SetNonSpaceWrap(),FontString, 1138
SetNormalFontObject(),Button, 1169
SetNormalTexture(),Button, 1170
SetNumber(),EditBox, 1237
SetNumeric(),EditBox, 1237
SetOffset(),ControlPoint, 1250
SetOffset(),Translation, 1254
SetOptOutOfLoot, 929
SetOrder(),Animation, 1247
SetOrder(),ControlPoint, 12501251
SetOrientation(),Slider, 1217
SetOrientation(),StatusBar, 1220
SetOrigin(),Rotation, 1252
SetOverrideBinding, 929930
SetOverrideBindingClick, 930
SetOverrideBindingItem, 930931
SetOverrideBindingMacro, 931
SetOverrideBindingSpell, 931932
SetOwner() GameTooltip, 1186
SetPadding(),GameTooltip, 1186
SetParent()
Animation, 1247
ControlPoint, 1251
Region, 1127
setting parent/child relationship, 145146
SetPartyAssignment, 932
SetPassword(),EditBox, 1237
SetPetAction() GameTooltip, 1186
SetPetStablePapderdoll, 932
SetPlayerTexture(),Minimap, 1194
SetPlayerTextureHeight(),Minimap,
11941195
SetPlayerTextureWidth(),Minimap, 1195
SetPOIArrowTexture(),Minimap, 1194
SetPoint(),Region, 11271128
SetPortraitTexture, 932933
SetPortraitToTexture, 161162, 933
SetPosition(),Model, 1200
SetPossession(),GameTooltip, 1187
SetPushedTextOffset(),Button, 1170
SetPushedTexture(),Button, 1170
SetPVP, 932
SetQuestItem(),GameTooltip, 1187
SetQuestLogItem(),GameTooltip, 1187
SetQuestLogRewardSpell(),GameTooltip, 1187
SetQuestLogSpecialItem(),GameTooltip, 1187
SetQuestRewardSpell(),GameTooltip, 1187
SetRadians(),Rotation, 1252
SetRaidDifficulty, 933
SetRaidRosterSelection, 933
SetRaidSubgroup, 934
SetRaidTarget, 934
SetResizable(),Frame, 11611162
SetReverse(), Cooldown, 1176
SetRotatesTexture(),StatusBar, 1220
SetRotation(),PlayerModel, 12011202
SetRotation(),Texture, 1143
SetScale(),Frame, 1162
SetScreenResolution, 934
SetScript(),ScriptObject, 1123
SetScrollChild(),ScrollFrame, 1207
SetScrollOffset(),ScrollingMessageFrame,
1230
1392 Index S–S
SetSelectedAuctionItem, 934935
SetSelectedBattlefield, 935
SetSelectedDisplayChannel, 935
SetSelectedFaction, 935
SetSelectedFriend, 935
SetSelectedIgnore, 936
SetSelectedMailCOD, 936
SetSelectedMailMoney, 936937
SetSelectedMute, 936
SetSelectedSkill, 936
SetSendMailItem(),GameTooltip, 1188
SetSendMailShowing, 937
SetSequence(),Model, 1200
SetSequenceTime(),Model, 12001201
SetShadowColor(),FontInstance, 11341135
SetShadowColor(),SimpleHTML, 1213
SetShadowOffset(),FontInstance, 1135
SetShadowOffset(),SimpleHTML, 12131214
SetShapeshift(),GameTooltip, 1188
SetSmoothing(),Animation, 12471248
SetSocketedItem(),GameTooltip, 1188
SetSocketGem(),GameTooltip, 1188
SetSpacing(),FontInstance, 1135
SetSpacing(),SimpleHTML, 1214
SetSpell(),GameTooltip, 1188
SetSpellByID(), GameTooltip, 1188
SetStartDelay(),Animation, 1248
SetStaticPOIArrowTexture(),Minimap, 1195
SetStatusBarColor(),StatusBar, 12201221
SetStatusBarTexture(),StatusBar, 1221
SetTalent(),GameTooltip, 1189
SetTaxiBenchmarkMode, 937
SetTaxiMap, 937938
SetTerrainMip, 938
SetTexCoord(),Texture, 11431144
SetTexCoordModifiesRect(),Texture,
11441145
SetText()
Button, 1170
customizing tooltip text, 453454
EditBox, 1238
FontString, 1138
GameTooltip, 1189
SimpleHTML, 12141215
SetTextColor(),FontInstance, 1135
SetTextColor(),SimpleHTML, 1215
SetTextHeight(),FontString, 1138
SetTextInsets(),EditBox, 1238
SetTexture(),Texture, 163, 1145
SetThumbTexture(),Slider, 1217
SetTimeVisible(),MessageFrame, 1225
SetTimeVisible(),ScrollingMessageFrame,
1230
SetToplevel(),Frame, 152, 1163
SetTotem(),GameTooltip, 1189
SetTracking, 938, 1190
SetTradeMoney, 938
SetTradePlayerItem(),GameTooltip, 1190
SetTradeSkillInvSlotFilter, 938
SetTradeSkillItem(),GameTooltip, 1190
SetTradeSkillItemLevelFilter, 938
SetTradeSkillItemNameFilter, 939
SetTradeSkillSubClassFilter, 939
SetTradeTargetItem(),GameTooltip, 1190
SetTrainerService(),GameTooltip, 1190
SetTrainerServiceTypeFilter, 939
SetTrainerSkillLineFilter, 939940
SetUIVisibility, 940
SetUnit(),GameTooltip, 1190
SetUnit(),PlayerModel, 1202
SetUnitAura(),GameTooltip, 1191
SetUnitBuff(),GameTooltip, 1191
SetUnitDebuff(),GameTooltip, 11911192
SetUpFullscreenScale, 941
SetUserPlaced(),Frame, 1163
SetValue(),Slider, 12171218
SetValueStep(),Slider, 1218
SetVertexColor(),LayeredRegion, 11301131
SetVerticalScroll(), ScrollFrame, 1207
SetView, 940
SetWatchedFactionIndex, 940
SetWhoToUI, 940941
SetWidth(),Region, 1128
SetWordWrap(),FontString, 1138
setZoom, 367, 1195
<Shadow> element, FontString, 165
shapeshift functions, 1101
shortcut evaluation, 13201322
shortcuts, string key, 5556
Show(),VisibleRegion, 1130
ShowBattlefiedList, 941
ShowBuybackSellCursor, 941
ShowCloak, 941
ShowContainerSellCursor, 942
ShowFriends, 942
ShowHelm, 942
ShowingCloak, 943
ShowingHelm, 943
ShowInventorySellCursor, 942
ShowMerchantSellCursor, 942
ShowMiniWorldMapArrowFrame, 943
ShowRepairCursor, 943
SignPetition, 943
simple conditionals, 4344
SimpleHTML widgets, 231232, 12081215
single () quote mark, strings, 2930
SitStandOrDescendStart, 943
size, object, 146147
<Size> XML element, 146
skeleton, creating addon, 269270
skill functions, 1096
slash commands
command tables, 345347
creating, 337339
Index SS 1393
overview of, 337
SlashCalc, 347349
summary, 347
tokenizing strings, 339341
tokenizing with patterns, 341345
SlashCalc, 347349
SlashCmdList, 337338
Sliders
creating scroll bars, 417419, 422423
reference guide, 12151218
scrolling and precision of, 423424
as widget type, 232
"slot" attribute, backward compatibility, 1325
slot IDs, 193194
snippets
control object running, 477
overview of, 463464
post-hooks, 484485
preserving state and controlling information,
473474
secure API functions, 475476
secure handler templates and, 467468
writing, 464
social functions, 10961097
SocketContainerItem, 943944
socketing functions, 10971098
SocketInventoryItem, 944
solid color, textures, 158159, 163
someFunction, 78–79
sort, Lua API, 1015
SortArenaTeamRoster, 944
SortAuctionApplySort, 944
SortAuctionClearSort, 945
SortAuctionSetSort, 945946
SortBattlefieldScoreData, 946
SortGuildRoster, 946947
sorting
array elements, 61
array of table data, 8890
attributes for secure group header, 503504
player’s inventory, 199
writing new function for, 248
SortLFG, 947
SortWho, 947
soulbound status, 461462
sound functions, 10981099
Sound_ChatSystem_GetInputDriverName
ByIndex, 947
Sound_ChatSystem_GetNumInputDrivers, 948
Sound_ChatSystem_GetNumOutputDrivers, 948
Sound_ChatSystem_GetOutputDriverName
ByIndex, 948
Sound_GameSystem_GetInputDriverName
ByIndex, 948
Sound_GameSystem_GetNumInputDrivers, 948
Sound_GameSystem_GetNumOutputDrivers, 948
Sound_GameSystem_GetOutputDriverName
ByIndex, 948
Sound_GameSystem_RestartSoundSystem, 948
source code management. See version control
systems
sourceFlags argument, combat events, 388
Sourceforge, 13541355
sourceGUID argument, combat events, 388
sourceNAME argument, combat events, 388
specifiers, format string, 96
spell (U) attributes,
SecureActionButtonTemplate, 292
spell functions, 10991101
SPELL prefix, combat events, 389
spellbookID, API meta-type, 555
SpellCanTargetGlyph, 948
SpellCanTargetItem, 948949
SpellCanTargetUnit, 949
SpellHasRange, 949
spellID, API meta-type, 555
spelling, tooltip, 452
SpellIsTargeting, 949
spells
casting, 289291
casting on different targets, 300302
choosing action by hostility, 298
SpellStopCasting, 949
SpellStopTargeting, 950
SpellTargetItem, 950
SpellTargetUnit, 950
SplitContainerItem, 950
SplitGuildBankItem, 950951
sqrt, Lua API, 1016
SquareGroupPetHeaderTemplate, 526
SquareUnitFrames
adding pets to, 523526
adjusting frame levels, 511
code for, 526535
constructing template for, 506508
creating header template for, 508509
creating SquareGroupPetHeaderTemplate, 526
displaying threat levels, 518519
displaying unit names, 521523
enhancing, 516
highlighting units on mouseover, 516517
overview of, 506
setting name and status bars, 509511
showing dead players, 519521
showing targeted units, 517518
StablePet, 950951
stance functions, 1101
standalone addon libraries, 13301332
standalone libraries, 1330
standingID, API meta-type, 555
StartAttack, 951
StartAuction, 951
StartDuel, 951
1394 Index S–T
StartMovie(),MovieFrame, 1205
StartMoving(),Frame, 1163
StartSizing(),Frame, 1163
stat information functions, 11011103
state
conditionals, 490491
drivers, 486487
preserving, 473474
responders, 487490
variables, 492
static tooltips, 453
status command, Subversion, 13421343
status text, 220224
StatusBar, 232233, 509511, 12191221
step_value,50
sticky anchors, 148
STOLEN, combat events, 395
Stop(),Animation, 1248
Stop(),AnimationGroup, 1242
stop attributes, 293
StopAnimating(),Region, 1128
StopAttack, 951
StopCinematic, 951
StopMacro, 952
StopMovie(),MovieFrame, 1205
StopMovingOrSizing(),Frame, 1163
StopMusic, 952
StopTradeSkillRepeat, 952
storing data, 5356, 62
StrafeLeftStart, 952
StrafeLeftStop, 952
StrafeRightStart, 952
StrafeRightStop, 952
strbyte, 1016
strchar, 10161017
strconcat, 108109, 1016, 1313
strfind, 1017
string keys, shortcuts, 55
string.find, 104105
string.format, 95–97
string.gmatch, 87, 102
string.gsub, 102104
string.len, 3233, 94
string.lower,94
string.match, 104
string.rep,95
string.reverse,95
strings
avoiding creation of unnecessary, 13121317
comparing, 2728
concatenating multiple, 28
converting numbers to, 2829
converting to numbers, 29
formatting new, 9598
functions accepting pattern, 102105
getting length of, 3233
implementing localization with, 136137
item, 195196
localizing with global, 13231324
minimizing unnecessary garbage, 13111312
quoting, 29–31
tokenizing generally, 339341
tokenizing with patterns, 341345
understanding Lua, 2733
utility functions, 9495
string.split, 339
string.sub, 7780, 95
string.uppers,95
strjoin, Lua API, 108, 10171018
strlen, Lua API, 1018
strlower, Lua API, 1018
strmatch, Lua API, 10181019
strrep, Lua API, 1019
strreplace, Lua API, 1019
strrev, Lua API, 10191020
strsplit, Lua API, 108, 1020
strsub, Lua API, 10201021
strtrim, Lua API, 1021
strupper, Lua API, 1021
Stuck, 952
__sub metamethod, 6971
subpatterns, graphic updates, 357
Subversion
commands, 13411343
creating local repository, 1343
layout of repository, 13401341
obtaining, 1341
overview of, 13391340
terminology, 1340
WoWInterface and, 1353
suffix, modified attributes, 296297
SUMMON, combat events, 393
SummonFriend, 952
summoning functions, 1103
svn add command, 1342
svn checkout command, 1341
svn commit command, 1342
svn diff command, 1343
svn log command, 1343
svn status command, 13421343
svn update command, 1342
svnadmin command, 1343
SwapRaidSubgroup, 952
swatchFunc attribute, ColorPicker, 441
SWING, combat events, 389
T
TabardModel type, 12021204
TabButtonTemplate template, 183
table constructor {}, 54–57
table library, functions, 9294
table of contents (TOC) file, addons, 125126
table.concat, 92, 1313, 1315
Index TT 1395
table.insert, 5860, 92
table.remove, 6061, 93
tables, 53–76
associative, 53
how to reduce garbage, 13121317
metatables. See metatables
minimizing unnecessary garbage, 13111312
object-oriented programming with, 6368
populated, 5556
recycling, 13181319
storing data using, 5356
using as arrays, 5661
using as logic structure, 13211322
using as namespaces, 6163
table.sort
sorting array elements, 61
sorting array of table data, 8789
sorting player’s inventory, 199
table library, 9394
tags, Subversion, 1341
tags, XML, 79
tail call recursion, 13151316
taint
creeping taint, 307308
enabling taint logging, 303304
execution taint, 304305
overview of, 302303
variable taint, 305307
TakeInboxItem, 953
TakeInboxMoney, 953
TakeInboxTextItem, 953
TakeTaxiNode, 953
talent functions, 11031104
target (U) attributes,
SecureActionButtonTemplate, 293
target specifiers, 491
targeted units, showing, 517518
targeting
functions, 11041105
unit on left click, 511512
TargetLastEnemy, 953
TargetLastFriend, 953
TargetLastTarget, 953
TargetNearest, 954
TargetNearestEnemy, 954
TargetNearestEnemyPlayer, 954
TargetNearestFriend, 954
TargetNearestFriendPlayer, 954
TargetNearestPartyMember, 954
TargetNearestRaidMember, 955
TargetTotem, 955
TargetUnit, 955
taunt messages, 353
taxi functions, 1105
TaxiGetDestX, 955956
TaxiGetDestY, 956
TaxiGetSrcX, 956
TaxiGetSrcY, 956957
TaxiNodeCost, 957
TaxiNodeGetType, 957
TaxiNodeName, 957958
TaxiNodePosition, 958
TaxiNodeSetCurrent, 958
templates
advantages of, 173174
creating header, 508509
creating SquareGroupPetHeaderTemplate, 526
frame. See frame templates
secure. See secure templates
for SquareUnitFrames, 506508
understanding, 171173
‘‘Terms of Use’’, WoW, 7
testing
addons, 12
CombatTrackerFrame, 272273
dropdown menus, 435436
update function, 200201
text
adding to frame with FontStrings, 164166
creating and updating status, 223224
custom text in tooltips, 453455
customizing text elements on dropdown
menus, 438439
displaying with FontStrings, 139
text attribute, dropdown menus, 438
TextBrowser addon, 155
textHeight attribute, dropdown menus, 438
textures, 150164. See also graphics
adding, 155156
adding layers of, 150153
alpha channels and, 374
BagBuddy design, 153154
coloring, 158160
creating in Lua, 162164
creating templates for, 173
defining BagBuddy’s background, 157158
finding graphics, 155
parenting, 145146
portrait, 160162
reference guide, 11381145
saving with GIMIP, 375
setting button, 175176
showing graphics and colors, 139
testing new, 383385
TGA format
overview of, 134
saving graphics in, 373
saving images in Paint Shop Pro, 382
saving images in Photoshop, 378
threat functions, 1105
threat levels, displaying, 518519
tick or tick marks, strings, 2930
time, Lua API, 10211022
timer code, 369370
1396 Index T–U
timer frames, 368
timestamp argument, combat events, 388
tinsert, Lua API, 1022
## Title: directive, addons, 127
TOC (table of contents) file, addons, 125126
toggle button, dropdown menus, 432433
ToggleAutoRun, 958
ToggleDropDownMenu(), 434435
ToggleInputLanguage(),EditBox, 1238
TogglePetAutocast, 958
TogglePVP, 958
ToggleRun, 958
ToggleSheath, 959
ToggleSpellAutocast, 959
toggling, dropdown menus, 434435
tokenization, 339343
tokens, 137, 339
tonumber
converting hexadecimal values to RGB, 78
converting strings to numbers, 29
Lua API, 1022
tooltips
accessing individual lines, 460
checking soulbound status, 461462
contents of, 453
custom text in, 453455
game element, 455458
getting information from, 460
information added to, 458
item information added to, 458459
overview of, 451452
summary, 462
types of, 452453
tooltiptext attribute, dropdown menus, 438
tooltipTitle attribute, dropdown menus,
438
toplevel attribute, frames, 152
tostring, 2829, 1022
tostring metamethod,D
71–72
totems, GUIDs for, 396397
tracking functions, 1106
trade functions, 11061107
tradeskill functions, 11071108
TradeSkillOnlyShowMakeable, 959
TradeSkillOnlyShowSkillUps, 959
trainer functions, 11081110
translation. See localization
Translation Animation type, 12531254
transparency/opacity. See alpha channels
tremove, Lua API, 10221023
triggered changes
general conditions, 493496
overview of, 486
state conditionals, 490491
state drivers, 486487
state responders, 487490
state variables, 492
unit conditions, 492493
troubleshooting, object visibility, 166
trunk directory, Subversion, 1340
TryOn(),DressUpModel, 1202
TurnInArenaPetition, 959960
TurnInGuildCharter, 960
TurnLeftStart, 960
TurnLeftStop, 960
TurnOrActionStart, 960961
TurnOrActionStop, 961
TurnRightStart, 961
TurnRightStop, 961
tutorial functions, 1110
TutorialsEnabled, 961
type, Lua API, 2324, 1023
U
UI Customization forums, IncGamers, 1351
<Ui> element, 132, 270271
UICheckButtonTemplate template, 182
UIDropDownMenu functions, 433434
UIDropDownMenu_JustifyText, 443
UIDropDownMenu_SetButtonWidth, 443
UIDropDownMenu_SetWidth, 443
UIErrorsFrame, 229
UIObject
FontInstance type, 11311132
overview of, 11211122
ParentedObject type, 1122
ScriptObject type, 11221123
UIPanelButtonTemplate template, 180
UIPanelCloseButton template, 180
UIPanelScrollBarTemplate template, 180
UIPanelTemplates.xml, 179183
UIPanelWindows, 250251
UIRadioButtonTemplate template, 183
UI/visual functions, 1110
__ (underscore characters, two), 69
Undress() method, DressUpModel, 1202
UninviteUnit, 961
unit argument, UNIT_COMBAT event, 269
unit conditions, 491493
unit frames. See frames
unit functions, 190192, 11101113
unit IDs, 188, 190192, 555556
unit watch system, 501
UNIT_COMBAT event
adding to CombatTracker.lua, 277
designing CombatTracker addon, 269
registering for, 244
responding to with OnEvent, 244245
UNIT_DESTROYED event, 396
UNIT_DIED event, 396
UNIT_PET, 409
UnitAffectingCombat, 962
Index UU 1397
UnitArmor, 962
UnitAttackBothHands, 962
UnitAttackPower, 962
UnitAttackSpeed, 963
UnitAura, 963964
UnitBuff, 964965
UnitCanAssist, 965
UnitCanAttack, 965
UnitCanCooperate, 965
UnitCastingInfo, 965966
UnitChannelInfo, 966
UnitCharacterPoints, 967
UnitClass, 967
UnitClassBase, 967968
UnitClassification, 968
UnitControllingVehicle, 968
UnitCreatureFamily, 968
UnitCreatureType, 969
UnitDamage, 969
UnitDebuff, 969970
UnitDefense, 970971
UnitDetailedThreatSituation, 971972
UnitExists, 972
UnitFactionGroup, 972
UnitGUID(), 396397
UnitGUID, 972973
UnitHasRelicSlot, 973
UnitHasVehicleUI, 973
UnitHealth, 973
UnitHealth function, 188
UnitHealthMax, 973974
UnitInBattleground, 974
UnitInParty, 974
UnitInRaid, 974
UnitInRange, 974975
UnitInVehicle, 975
UnitInVehicleControlSeat, 975
UnitIsAFK, 975
UnitIsCharmed, 975976
UnitIsConnected, 976
UnitIsControlling, 976
UnitIsCorpse, 976
UnitIsDead, 976977
UnitIsDeadOrGhost, 977
UnitIsDND, 976
UnitIsEnemy, 977
UnitIsFeignDeath, 978
UnitIsFriend, 978
UnitIsGhost, 978
UnitIsInMyGuild, 978
UnitIsPartyLeader, 979
UnitIsPlayer, 979
UnitIsPossessed, 979980
UnitIsPVP, 978
UnitIsPVPFreeForALL, 979
UnitIsPVPSanctuary, 979
UnitIsRaidOfficer, 980
UnitIsSameServer, 980
UnitIsSilenced, 980
UnitIsTalking, 980
UnitIsTapped, 980981
UnitIsTappedByAllThreatList, 981
UnitIsTappedByPlayer, 981
UnitIsTrivial, 981982
UnitIsUnit, 982
UnitIsVisible, 982
UnitLevel, 982
UnitName, 982983
UnitOnTaxi, 983
UnitPlayerControlled, 983984
UnitPlayerOrPetInParty, 984
UnitPlayerOrPetInRaid, 984
UnitPower, 984
UnitPowerMax, 984985
UnitPowerType, 985
UnitPVPName, 983
UnitRace, 985986
UnitRangedAttack, 986
UnitRangedAttackPower, 986
UnitRangedDamage, 986
UnitReaction, 986987
UnitResistance, 987
units
creating complex action button, 300302
displaying unit names, 521523
flags, 398400
GUIDs for, 396397
highlighting on mouseover, 516517
showing targeted, 517518
specifying, 291
targeting on left click, 511512
UnitSelectionColor, 987988
UnitSex, 988
UnitStat, 988
UnitSwitchToVehicleSeat, 988
UnitTargetsVehicleInRaidUI, 989
UnitThreatSituation, 989
UnitUsingVehicle, 989990
UnitVehicleSeatCount, 990
UnitVehicleSeatInfo, 990
UnitVehicleSkin, 990991
UnitXP, 991
UnitXPMax, 991
UnlockHighlight() method, Button, 1170
__unm metamethod, 71
unpack, Lua API, 10231024
UnregisterAllEvents(),Frame, 1163
UnregisterEvent(), 244, 11631164
UnstablePet, 991
update command, Subversion, 1342
update function
altering for page navigation, 221222
displaying player’s inventory, 198201
filtering by name, 226227
1398 Index U–V
update function (continued)
pet mappings, 405
testing, 200201
UpdateAddOnCPUUsage, 991
UpdateColorByID(),ScrollingMessageFrame,
1230
UpdateGMTicket, 991992
UpdateMapHighlight, 992
UpdateScrollChildRect() method,
ScrollFrame, 1208
UpdateSettings, 992
UpdateSpells, 992
UseAction, 992993
UseContainerItem, 993
UseEquipmentSet, 993994
UseInventoryItem, 994
UseItemByName, 994
UseQuestLogSpecialItem, 994
user experience, CombatTracker, 267268
user input, WoW interface recognizing, 309
user interface, 34. See also addons
User Interface Customization tool, XML, 8586,
127
UseSoulstone, 994
UTF-8, 521522
util table, 62
utility functions
added to Lua in WoW, 108109
capture(), 361362
creating namespace of, 62
overview of, 11131115
V
validation, XML document, 115117
values
caching frequently accessed, 1322
calculating for loops, 50
comparing, 2627
defined, 23
function arguments and return,
41–42
functions as Lua, 42
multiple return, 7780
types of, 23–24
understanding Lua, 2327
understanding nil, 35
variables vs., 23
vararg functions, 8284
variable arguments, 361, 1314
variable scope, 5051
variable taint, 305308
variables
## SavedVariables:, addons, 130
## SavedVariablesPerCharacter:, addons,
130
assigning, 2526
assigning multiple, 26
comparing values, 2627
global vs. local, 3537
local, 13101311
Lua, 2327
meaningful names, 13061307
named constants vs. literals, 13071308
naming exceptions, 1307
overview of, 2425
reducing garbage, 1312
specifying specific values, 80
state, 492
valid names, 25
values vs., 23
vehicle functions, 11151116
VehicleAimDecrement, 994
VehicleAimDownStart, 995
VehicleAimDownStop, 995
VehicleAimGetAngle, 995
VehicleAimGetNormAngle, 995
VehicleAimIncrement, 995
VehicleAimRequestAngle, 995
VehicleAimRequestNormAngle, 995996
VehicleAimUpStart, 996
VehicleAimUpStop, 996
VehicleCameraZoomIn, 996
VehicleCameraZoomOut, 996
VehicleExit, 996
VehicleNextSeat, 996
VehiclePrevSeat, 996
version, game, 126127
version control systems
Git and Mercurial, 13441348
overview of, 1339
Subversion, 13391343
video functions, 11161117
visibility of objects, 166
VisibleRegion type, 11291130
voice functions, 11171119
VoiceChat_GetCurrentMicrophoneSignal
Level, 996
VoiceChat_IsPlayingLoopbackSound, 996
VoiceChat_IsRecordingLoopbackSound,
997
VoiceChat_PlayLoopbackSound, 997
VoiceChat_RecordLoopbackSound, 997
VoiceChat_StopPlayingLoopbackSound,
997
VoiceChat_StopRecordingLoopbackSound,
997
VoiceEnumerateCaptureDevices, 997
VoiceEnumerateOutputDevices, 997
VoiceGetCurrentCaptureDevice, 998
VoiceGetCurrentOutputDevice, 998
VoiceIsDisabledByClient, 998
VoiceSelectCaptureDevice, 998
VoiceSelectOutputDevice, 998
Index WW 1399
W
WebLua, 15
well-formed XML, 114115
while loops, 49
while statement, 4648
whitespace, 342, 1309
widget scripts, 12551275
addons and, 139140
hooking, 362
OnAnimFinished, 1255
OnAttributeChanged, 1255
OnChar, 12551256
OnCharComposition, 1256
OnClick, 12561257
OnColorSelect, 12571258
OnDisable, 1258
OnDoubleClick, 1258
OnDragStart, 12581259
OnDragStop, 12591260
OnEditFocusGained, 1260
OnEditFocusLost, 1260
OnEnable, 1260
OnEnter, 12601261
OnEnterPressed, 1261
OnEscapePressed, 1261
OnEvent, 12611262
OnFinished, 1262
OnHide, 1262
OnHorizontalScroll, 1262
OnHyperlinkClick, 12621263
OnHyperlinkEnter, 1263
OnHyperlinkLeave, 12631264
OnInputLanguageChanged, 1264
OnKeyDown, 1264
OnKeyUp, 12641265
OnLeave, 1265
OnLoad, 1265
OnLoop, 12651266
OnMessageScrollChanged, 1266
OnMinMaxChanged, 1266
OnMouseDown, 1266
OnMouseUp, 12661267
OnMouseWheel, 1267
OnMovieFinished, 1267
OnMovieHideSubtitle, 1268
OnMovieShowSubtitle, 1268
OnPause, 1268
OnPlay, 1268
OnReceiveDrag, 1268
OnScrollRangeChanged, 1269
OnShowChanged, 1269
OnSizeChanged, 12691270
OnSpacePressed, 1270
OnStop, 1270
OnTabPressed, 1270
OnTextChanged, 1270
OnTextSet, 1271
OnTooltipAddMoney, 1271
OnTooltipCleared, 1271
OnTooltipSetAchievement, 1271
OnTooltipSetDefaultAnchor, 1272
OnTooltipSetEquimentSet, 1272
OnTooltipSetFrameStack, 1272
OnTooltipSetItem, 1272
OnTooltipSetQuest, 1272
OnTooltipSetSpell, 1273
OnTooltipSetUnit, 1273
OnUpdate, 1273
OnUpdateModel, 12731274
OnValueChanged, 1274
OnVerticalScroll, 1274
PostClick, 12741275
PreClick, 1275
widget types
Animation.See Animation types
AnimationGroup, 12381242
Button, 11641170
CheckButton, 11701172
ColorSelect, 11721175
ControlPoint, 12501251
Cooldown, 11751176
DressUpModel, 11751176, 1202
EditBoxes, 12311238
exploring, 227233
Font object, 12211222
FontInstance, 11311135
FontStrings, 11351138
Frame.See frames
GameTooltip.See GameTooltip frame type
LayeredRegion, 11301131
MessageFrames, 12221225
Minimap, 11921195
Model frame type, 11951201
ParentedObject, 1122
Path Animation, 12481250
PlayerModel, 12011202
Region, 11241128
ScriptObject, 11221123
ScrollFrame, 12061208
SimpleHTML, 12081215
StatusBar, 12191221
TabardModel, 12021204
Texture, 11381145
UIObject, 11211122
VisibleRegion, 11291130
widgets, 207241
adding clickable buttons, 212219
adding name filter, 224227
code, 233241
handler arguments, 13241325
making buttons interactive, 207212
navigating multiple pages, 219224
reference guide. See widget scripts; widget
types
1400 Index W–Z
wipe, Lua API, 1024
WithdrawGuildBankMoney, 998
working copy, Subversion, 1340
WoW (World of Warcraft)
best practices, 13231325
defined, 3
forums, 13491350
function aliases added to Lua in,
109110
hosting specific to, 13521353
multiple return values in, 7980
string.format(), 97–98
utility functions, 108109
XML, 117120
WoW (World of Warcraft) API, 187205
code, 204205
finding right functions, 201203
FrameXML functions, 189
library-like APIs, 188189
normal APIs, 188
protected functions, 189190
querying item information for BagBuddy,
193197
understanding, 187188
unit functions, 190192
writing bag scanner, 198201
Wow programming forums, 1350
WowAce, 1350, 1353
#wowace on irc.freenode.net, 1351
WoWInterface, 1350, 1352
WoWLua, 1415
#wowprogramming on irc.freenode.net,
13511352
#wowuidev on irc.freenode.net, 1351
wrapping frame scripts
creating click wrapper, 483484
overview of, 482483
post-hook snippet for, 484485
script wrapper reference, 485486
Wrath of the Lich King expansion, 518
X
x-label directives, addons, 131
XML (eXtensible Markup Language)
addon anatomy, 132134
components, 112113
creating scroll bars, 418419
creating well-formed, 114115
document validation, 115117
as markup language, 111112
texture definitions, 384385
in World of Warcraft, 117120
XML hierarchy, setting parent/child
relationship, 145
XML Schema, 81
XMLNanny, 8283
XMLSpy, 82
XMLValidate utility, 81
XMLValidator, 82
xor, 390
xpcall, Lua API, 1024
Z
zone information functions, 1119
ZoomOut, 999
James Whitehead II
Rick Roe
A Guide and Reference for Creating WoW Addons
Whitehead • Roe
$49.99 US • $59.99 CAN
Computer Graphics / Game Programming
Visit our Web site at www.wiley.com/compbooks
Front cover art © Scott Johnson/FrogPants Studios
®
Your secret weapon against
the Lich King’s wrath
World of Warcraft has entered a new dimension. Take command of it by modifying the interface
with your own unique addons. Whether your goal is to enhance addons you already use, to
enlarge your arsenal by creating some all-new features, or to immerse yourself in the programming
as well as the game, this book will be your oracle. Learn the arcane languages of Lua and XML
and master the craft of addon creation!
Understand the anatomy of an addon
Work with frames, widgets, and other graphical elements
Explore basic and advanced functions and control structures
Track damage with CombatTracker, and respond to the combat log
and threat information
Track, lter, and sort your inventory by writing BagBuddy,
a fully functional addon
Create slash commands, custom graphics, scroll frames, and
dropdown menus
Who are you?
Apprentice programmers with no prior experience — learn Lua and XML in Part I
Journeymen who have done some programming — skim Part I and start with the details about addon creation in Part II
Master programmers with addons already in their arsenal — dive right into Advanced Addon Techniques in Part III
James Whitehead II, aka Cladhaire, is the creator of PerfectRaid, Clique, TomTom, and LightHeaded, and coauthor of
Hacking
World of Warcraft
.
Rick Roe, aka the crazy goblin tinker Gazmik Fizzwidget, created Feed-O-Matic, FactionFriend, and some other addons so
awesome that Blizzard rolled their functionality into its new UI.
®

Navigation menu