# Forum > World of Warcraft > World of Warcraft Bots and Programs > Probably Engine >  Probably Engine Documentation: A Complete Guide

## ImogenOC

*Probably Engine Documentation*

Welcome to the... Massive PE documentation thread I've assembled after over a year of bitching from members. This will contain just about everything PE has to offer, including installation, checksums, and legible explanations to bloody everything.


*Sorted in easy to find Ctrl + F & Hyperlink for your viewing pleasure.*

Index is sorted as explained below:

ex. 1_2_3_4. Title

1 = Chapter Identifier
2 = Section Identifier
3 = Subsection Identifier
4 = Sub-Subsection Identifier (we need to go deeper)
. = End identifier
Title = Human Readable Title
*Index*
*
1. Introduction (Probably Engine Documentation: A Complete Guide)
2. About
3. Installation
4. Usage and Information
5. Documentation - Preamble
6. Custom Rotations - Foreword
7. Probably Source - Explained
8. Rotation Developement
9. Conditions
10. States
11. ??? Coming Soon ???*
*1. Introduction
*
1_1. What is PE?
1_2. What does PE do?
1_3. What does PE require?
1_3_1. [Win/64] Firehack
1_3_2. [Win/32] Caelus
1_3_3. [Win/32/64] oLua
1_3_4. [Win/32] EWT - Easy Wow Toolbox
1_3_5. [OSX/10.9+] WoWSX
1_3_6. [Win/32] OffSpring
1_4. Does this break Blizzard's ToS?
1_5. Where can I go for support?
1_6. Do you take donations?

*2. About
*
2_1. Legacy
2_2. Developers
2_3. Phelps
2_4. Tao
2_5. Hackinte
2_6. root1user
2_7. Woe
2_8. Imogen
2_9. Sassy Comments and Updates
2_10. **** Line 24

*3. Installation
*
3_1. Download
3_2. Wow Install Location
3_3. Installing
3_4. File Hierarchy
3_5. Git / SVN
3_6. Confirmation
3_6_1. In Game Confirmation

*4. Usage and Information
*
4_1. Unlocking
4_2. Commands
4_3. Enabling
4_4. Toggles and Modifiers
4_5. In / Out of Combat
4_6. Debugging
4_7. Bug Reporting
4_8. Custom Rotations
4_9_1. Installation
4_9_2. Confirmation
4_9_3. Profile Selection

*5. Documentation - Preamble
*
5_1. Disclaimer
5_2. Documentation Layout
5_3. Support
5_4. Sharing your work

6. *6. Custom Rotations - Foreword
* (See 8. for complete synopsis)
6_1. Creation and Programs
6_2. File Hierarchy
6_3. .toc
6_4. Hosting Options
6_5. Support

*7. Probably Source - Explained
*
7_1. PREAMBLE
7_2. external
7_2_0. PREAMBLE
7_2_1. AceConfig
7_2_2. AceConsole
7_2_3. AceGUI
7_2_4. CallbackHandler
7_2_5. DiesalGUI
7_2_6. DiesalMenu
7_2_7. DiesalStyle
7_2_8. DiesalTools
7_2_9. LibBoss
7_2_10. LibBossIDs
7_2_11. LibDispellable
7_2_12. LibDraw
7_2_13. LibRangeCheck
7_2_14. LibSharedMedia
7_2_15. LibStub
7_3. interface
7_3_0. PREAMBLE
7_3_1. buttons
7_3_2. commands
7_3_3. locale
7_3_4. buttons.lua
7_3_5. config.lua
7_3_6. custom.lua
7_3_7. interface.lua
7_3_8. locale.lua
7_3_9. log.lua
7_3_10. manager.lua
7_3_11. minimap.lua
7_3_12. toggle.lua
7_3_13. tracker.lua
7_4. rotations
7_4_1. deathknight
7_4_2. druid
7_4_3. hunter
7_4_4. mage
7_4_5. monk
7_4_6. paladin
7_4_7. priest
7_4_8. rogue
7_4_9. shaman
7_4_10. shared
7_4_11. warlock
7_4_12. warrior
7_5. system
7_5_1. conditions
7_5_1_1. core.lua
7_5_1_2. states.lua
7_5_2. core
7_5_2_1. command.lua
7_5_2_2. condition.lua
7_5_2_3. config.lua
7_5_2_4. debug.lua
7_5_2_5. dsl.lua
7_5_2_6. library.lua
7_5_2_7. listener.lua
7_5_2_8. module.lua
7_5_2_9. overloads.lua
7_5_2_10. parser.lua
7_5_2_11. raid.lua
7_5_2_12. rotation.lua
7_5_2_13. set.lua
7_5_2_14. timeout.lua
7_5_2_15. timer.lua
7_5_2_16. tooltip.lua
7_5_3. listeners
7_5_4. modules
7_5_4_1. combat_tracker.lua
7_5_4_2. config.lua
7_5_4_3. disarm.lua
7_5_4_4. faceroll.lua
7_5_4_5. keymanager.lua
7_5_4_6. pet.lua
7_5_4_7. player.lua
7_5_4_8. queue.lua
7_5_4_9. target.lua
7_5_4_10. tooltip.lua
7_5_4_11. tracker.lua
7_5_5. protected
7_5_5_1. base.lua
7_5_5_2. firehack.lua
7_5_5_3. generic.lua
7_5_5_4. offspring.lua
7_5_6. timers
7_6. bindings.xml
7_7. LICENSE
7_8. probably.lua
7_9. probably.toc
7_10. probably.xml
7_11. README.md
7_12. version.txt

*8. Rotation Developement
*
8_0. Setup Verification
8_1. Rotation Formatting
8_2. Spell Thread
8_3. SpellID vs SpellName
8_4. Nesting
8_5. Custom Functions
8_6. Custom Toggles
8_7. Bug Testing

*9. Conditions
*
9_0. PREAMBLE
9_1. disspellable
9_2. buff
9_3. buff.any
9_4. buff.count
9_5. debuff
9_6. debuff.any
9_7. debuff.count
9_8. debuff.duration
9_9. buff.duration
9_10. aura.crit
9_11. aura.crits
9_12. aura.avg
9_13. aura.last
9_14. aura.low
9_15. aura.high
9_16. aura.total
9_17. aura.stacks
9_18. aura.time
9_19. aura.uptime
9_20. stance
9_21. form
9_22. seal
9_23. focus
9_24. holypower
9_25. shadoworbs
9_26. energy
9_27. solar
9_28. lunar
9_29. eclipse
9_30. timetomax
9_31. tomax
9_32. rage
9_33. chi
9_34. demonicfury
9_35. embers
9_36. soulshards
9_37. behind
9_38. infront
9_39. disarmable
9_40. combopoints
9_41. alive
9_42. dead
9_43. swimming
9_44. exists
9_45. modifier.shift
9_46. modifier.control
9_47. modifier.alt
9_48. modifier.lshift
9_49. modifier.lcontrol
9_50. modifier.lalt
9_51. modifier.rshift
9_52. modifier.rcontrol
9_53. modifier.ralt
9_54. modifier.player
9_55. classifacation
9_56. boss
9_57. id
9_58. toggle
9_59. modifier.toggle
9_60. modifier.taunt
9_61. threat
9_62. agro
9_63. balance.sun
9_64. balance.moon
9_64. moving
9_65. lastmoved
9_66. movingfor
9_67. ruinicpower
9_68. runes.count
9_69. runes.frac
9_70. runes.depleted
9_71. runes
9_72. health
9_73. health.actual
9_74. health.max
9_75. mana
9_76. raid.health
9_77. modifier.multitarget
9_78. modifier.cooldowns
9_79. modifier.cooldown
9_80. modifier.interrupts
9_81. modifier.interrupt
9_82. modifier.last
9_83. lastcast
9_84. enchant.mainhand
9_85. enchant.offhand
9_86. totem
9_87. totem.duration
9_88. mushrooms
9_89. casting.time
9_90. casting.delta
9_91. casting.percent
9_92. channeling
9_93. interruptsat
9_94. interruptat
9_95. spell.cooldown
9_96. spell.recharge
9_97. spell.usable
9_98. spell.exists
9_99. spell.casted
9_100. spell.charges
9_101. spell.cd
9_102. spell.range
9_103. talent
9_104. friend
9_105. enemy
9_106. glyph
9_107. range
9_108. distance
9_109. level
9_110. combat
9_111. time
9_112. deathin
9_113. ttd
9_114. role
9_115. name
9_116. modifier.part
9_117. modifier.raid
9_118. party
9_119. raid
9_120. modifier.members
9_121. creatureType
9_122. class
9_123. falling
9_124. timeout
9_125. hashero
9_126. buffs.stats
9_127. buffs.stamina
9_128. buffs.attackpower
9_129. buffs.attackspeed
9_130. buffs.haste
9_131. buffs.spellpower
9_132. buffs.crit
9_133. buffs.critical
9_134. buffs.mastery
9_135. buffs.multistrike
9_136. buffs.multi
9_137. buffs.vers
9_138. buffs.versatility
9_139. charmed
9_140. vengeance
9_141. area.enemies
9_142. area.friendly
9_143. ilevel
9_144. firehack
9_145. offspring

*10. States*
10_0. PREAMBLE
10_0. PREAMBLE
10_1. state.purge
10_2. state.charm
10_3. state.disarm
10_4. state.disorient
10_5. state.dot
10_6. state.fear
10_7. state.incapacitate
10_8. state.misc
10_9. state.root
10_10. state.silence
10_11. state.sleep
10_12. state.snare
10_13. state.stun
10_14. immune.all
10_15. immune.charm
10_16. immune.disorient
10_17. immune.fear
10_18. immune.incapacitate
10_19. immune.melee
10_20. immune.silence
10_21. immune.polly
10_22. immune.misc
10_23. immune.sleep
10_24. immune.snare
10_25. immune.spell
10_26. immune.stun

*11. ??? Coming Soon ???*

----------


## ImogenOC

*1. Introduction*
*1_1. What is PE?*
PE is a short (and commonly used) abbreviation for ProbablyEngine, a unique World of Warcraft addon.

*1_2. What does PE do?*
ProbablyEngine, with the help of a lua unlocker, access WoW's native API to automate your rotations in line with what the rotation loaded is coded to do; this means that you could do anything from something perfect or SimCraft style, to a utility rotation, or even a simple burst rotation for the pros out there that want control. Some people use it for crowd control, others just for the easy intelligence to hotkeys.

OR, if you don't like the idea of being against Blizzard's EULA and ToS, we have an additional mode that highlights the spell to cast with a green skull. Make sure you don't use something like Bartender or it'll be all messed up.

ProbablyEngine supports custom skins for most major UI overhauls like ElvUI.

*1_3. What does PE require?*
A Lua Unlocker for World of Warcraft's latest patch and offsets, with a minimum of releasing the CastSpellByName protected function. You can find a number of good unlockers below, for both Mac and Windows.

Unlockers recieve two classifacations by the ProbablyTeam; Simple and Advanced.
Simple unlockers do the bare minimum, allow us to automate your rotation and nothing more.
Advanced unlockers allow us to dip deeper;
-> Measure Distance
-> Track Units
-> Check LoS
-> Calculate Units within distance
And such.

*1_3_1. [Win/64] Firehack*
*Introduction*
FireHack is a multitool developed and maintained by lol1dk. It provides not just Lua Unlocking for the client, but also some additional tools to help you around with... Hacking, really.

*Classifacation*
Availability: Paid - Subscription (3.99/mo, 10.99/90d)
ProbablyEngine Classifacation: Advanced Unlocker

*Features*
Fly Hack
Hover Hack
Climb Hack
Water Walk Hack
Always Facing Hack
Collision Hack***
Custom Lua API
Lua Scripts
Lua Unlock
In-Game UI***
Warden Protection
Auction Time Hack***
View All Levels Hack
Zoom Hack
No Away Hack
Moving Loot Hack***
Follow Hack
Tracking Hack***
No Knockback Hack***
Obscure Target Hack***
Morph Hack***
Mount Morph Hack***
Scale Hack***
Rendering Hack***
Stopfall Hack
Spectator Hack***
Camera Target Hack***
Loot While Mounted Hack
Wireframe Hack***
Colliding Rendering Hack - Not yet supported in the WoD update
Watermarking Disabler - Not yet supported in the WoD update

*** - Not YET Supported in WoD
*Summary*
FireHack has the most features, is the most established, and updates within hours of a patch. lol1dk, while slow with feature updates, is the most creditable in the scene for what he does.

*1_3_2. [Win/32] Caelus*
*Introduction*
Caelus, developed by -Ryuk-, is new to the scene as a hacktool. Released mid February of 2015, this uprising tool is ready to give FireHack a run for it's money. But as always, be careful with new tools.
Caelus should classify as a basic unlocker, but it has a few tools that make it advanced in nature.

*Classifacation*
Availability: Paid - Subscription (7.99/mo)
ProbablyEngine Classifacation: Advanced Unlocker

*Features*
Teleport
Fly
Hover
Unlimited Jumps
StopFall
WaterWalk
M2Collision (Decorations)
WMOCollision (Structures)
AntiAFK
FollowAny
LuaUnlock

*Summary*
FireHack Jr.
-Ryuk- is steadily releasing new updates and features, so it's well worth the investment if you want the extra tools.

*1_3_3. [Win/32/64] oLua*
*Introduction*
oLua, developed by the legendary DarkLinux, is unique in this playing field. oLua DOSEN'T write to WoW's memory, functioning nearly out of process. Great for those of you who are excessively timid in hacking.

*Classifacation*
Availability: Free
ProbablyEngine Classifacation: Simple Unlocker

*Features*
LuaUnlock
-> Scripts
-> Macros
-> Addons
AntiAFK
x32 & x64!

*Summary*
For the timid. It's a simple unlocker, so if all you want is to automate a rotation this is perfect.

*1_3_4. [Win/32] EWT - Easy Wow Toolbox*
*Introduction*
EWT, developed by Reliasn, is a multitool / bot. It's adorably powerful, useful, and lightweight.

*Classifacation*
Availability: Free
ProbablyEngine Classifacation: Advanced Unlocker

*Features*
FishBot
ProfileMaker
Grind Bot
GatherBot
AutoKeySpam
Auto-Update
Target/Near Alert
Smart Targetting
Persistent Morph
AntiAFK
Rotation Bot (If you REALLY dislike PE that much...)
LuaUnlock
OffsetFinder
Object/Unit Spy
Hide Player Render - Great for patch day swarms
Black Market Timers

*Summary*
Far more powerful than people give it credit for, I recommend this to anyone who frequently uses HonorBuddy alongside it.

*1_3_5. [OSX/10.9+] WoWSX*
*Introduction*
WoWSX, developed by the legendary JuJuBoSc, is a currently free hack tool for WoW built for Macintosh. 

*Classifacation*
Availability: Free (During Beta)
ProbablyEngine Classifacation: Advanced Unlocker

*Features*
LuaUnlock
ProbablyEngine Support
FlyHack
Waterwalk
FollowAny
ClimbHack
AntiAFK
Morph

*Summary*
Same with Caelus, except for Mac.

*1_3_6. [Win/32] Offspring*
*Introduction*
Offspring, developed by WildBreath, is unique to the field in it's deployment. OffSpring deploys as a command and API system instead of an out of process program.

*Classifacation*
Availability: Free
ProbablyEngine Classifacation: Advanced Unlocker

*Features*
DirectX Independent
Custom LuaUnlock (seethread)
Injection Based
Offset Finder

*Summary*
A Free, advanced classifacation unlocker. Surprisingly power, and compact. A lovely little tool.

*1_4. Does this break Blizzard's ToS?*
Of course. I thought you knew that.

*1_5. Where can I go for support?*
OwnedCore
WebChat
IRC: irc://104.167.105.217:6667/probably

*1_6. Do you take donations?*
Ownedcore frowns upon donation links, so if you are THAT insistent, give us a visit in our IRC.

----------


## ImogenOC

*2. About*

*2_1. Legacy*
ProbablyEngine is an old project, with some of the source dating back over three years. Initial developement began by Phelps, until he was prosecuted by Blizzard Legal repeatedly under tort law.

*2_2. Developers*
ProbablyEngine is opensource, and as such, has dozens of 'developers'. Most updates are now carried out by Hackinte and Woe.

*2_3. Phelps*
The famous and infamous Phelps, previously benphelps, was the initial developer for ProbablyEngine. He has since left the project and dropped off the face of the earth.

*2_4. Tao*
Tao, a mysterious figure with skill exceeding all who have touched the project, gifted us numerous critical updates to the core engine before disappearing from whence he came.

*2_5. Hackinte*
Current lead developer, Hackinte picked up the position months after Phelps poofed, and has continued the project in stride.

*2_6. root1user*
A mysterious, sassy, quirky developer that existed back before the initial PQR/PE/Glider banwave in February of 2014. He disappeared early January of 2014.

*2_7. Woe*
Another quiet and intelligent developer that works side by side with Hackinte. You don't hear from him much.

*2_8. Imogen*
As stubborn, friendly, and snarky person in real life, these personalities carry over into her work as community manager for PE. She handles the people so the developers don't have to, including most general support.

*2_9. Sassy Comments and Updates*
ProbablyEngine has a history of sassy comments and updates to Git, with many uses of profanity and curse such as:

F*** - 12 Uses
Stupid - 1 Use
S*** - 3 Uses
wtf - 1 use

Most core files have amusing comments, such as:
probably/system/core/parser.lua:110-117
probably/system/core/library.lua:26
probably/system/core/dsl.lua:26 (The famous/infamous line 24 comment)
probably/system/core/dsl.lua:39-41
probably/system/core/dsl.lua:124-125
probably/system/core/dsl.lua:136

And many more for you to find.

*2_10. **** Line 24* 
Historically, line 24 in probably/system/core/dsl.lua handled our comparator before one day dieing. The section was rewritten multiple times, moved, deleted, and made into an entire comment. It was always line 24 until an entire work around was made.

----------


## ImogenOC

*3. Git / SVN*

*3_1. Download*
Most recent download can be found in this thread.

*3_2. Wow Install Location*
Unless using a custom install location, you can find your install under
(64x PC)
C:\Program Files (x86)\World of Warcraft
(32x PC)
C:\Program Files\World of Warcraft

*3_3. Installing*
Installation is simple! We install just like any other addon.
1. Download the addon from this thread.
2. Unzip to your addons directory at C:\Program Files (x86)\World of Warcraft\interface\addons
3. Restart or Start your client, confirm enabled in your addons list.
4. ???
5. Profit!

*3_4. File Hierarchy*
C:\Program Files (x86)\World of Warcraft\interface\addons\Probably
or
C:\Program Files\World of Warcraft\interface\addons\Probably

Confirmation of proper install hierachy if you can find this file
C:\Program Files (x86)\World of Warcraft\interface\addons\Probably\*probably.toc*
in the root folder.

*3_5. Git / SVN*
Yup!
https://gitlab.com/probablyengine/probably
TurtleSVN should allow you to update straight from there, else use any normal git program.

For more information, see this thread.

*3_6. Confirmation*
Again, you should see the Probably folder inside your
C:\Program Files (x86)\World of Warcraft\interface\addons\ folder.
What, do you need a .sfv to make sure you did it right?

Check your Addons List for Probably, if it's there then you are good to go!

*3_6_1. In Game Confirmation*
See four little boxes in the center there? Bingo, you've successfully installed ProbablyEngine.

----------


## ImogenOC

*4. Usage and Information*

*4_1. Unlocking*
Load up your unlocker of preference and inject/enable. If it's an advanced unlocker, ProbablyEngine will report it's name and confirmation. If it is a simple unlocker, ProbablyEngine will report as such.

From C:\Program Files (x86)\World of Warcraft\interface\addons\Probably\interface\locale\enUS.lua:


```
   65: pels('unlock_generic', 'Detected a generic Lua unlock!  Some advanced features will not work.')
   66  pels('unlock_none', 'No unlock found, now in FaceRoll mode, /reload your UI to check again.')
   67: pels('unlock_firehack', 'Detected FireHack!')
   68: pels('unlock_offspring', 'Detected OffSpring!')
   69  pels('offspring_los_warn', 'OffSpring does not support LoS from an arbitrary unit, only player.')
```

Unlocker relevant files:


```
C:\Program Files (x86)\World of Warcraft\interface\addons\Probably\system\protected\firehack.lua:
C:\Program Files (x86)\World of Warcraft\interface\addons\Probably\system\protected\generic.lua:
C:\Program Files (x86)\World of Warcraft\interface\addons\Probably\system\protected\offspring.lua:
C:\Program Files (x86)\World of Warcraft\interface\addons\Probably\system\protected\base.lua
```


*4_2. Commands*
ProbablyEngine registers some commands locally to make your life easier.



```
/pe - Full Help List (Aliases use additonal, e.g. /pe ?
Aliases:
help
?
wat


/pe v - Displays current version
Aliases:
ver
version


/pe ui - Shows/Hides the user interface, will function regardless of current state.
Aliases:
toggleui


/pe toggle - Toggles on or off. Uses current inverse.

/pe enable - Turns the addon on.

/pe disable - Turns the addon off.

/pe cd - Enables master toggle 'Cooldowns'
Aliases:
cooldown
cooldowns


/pe kick - Enables use of interrupts.
Aliases:
silence
interrupt
interrupts


/pe aoe - Enables AoE rotation
Aliases:
multitarget


/pe al - Enables the Action Log.
Aliases:
log
actionlog


/pe lag - Changes the spacing between actions.
Aliases
cycletime:


/pe turbo - Enables usage of spell clipping, such as interrupting Mind Flay or a current cast if it's parameters become void.
Aliases:
godmode
```

RAW: C:\Program Files (x86)\World of Warcraft\interface\addons\Probably\interface\commands\core.lua


```
-- ProbablyEngine Rotations
-- Released under modified BSD, see attached LICENSE.

local L = ProbablyEngine.locale.get

ProbablyEngine.command.help = {

}

ProbablyEngine.command.register_help = function(key, help)
  ProbablyEngine.command.help[key] = help
end

ProbablyEngine.command.register_handler({'version', 'ver', 'v'}, function()
  ProbablyEngine.command.print('|cff' .. ProbablyEngine.addonColor .. 'ProbablyEngine |r' .. ProbablyEngine.version)
end)
ProbablyEngine.command.register_help('version', L('help_version'))

ProbablyEngine.command.register_handler({'toggleui', 'ui'}, function()
  ProbablyEngine.config.write('uishown', not ProbablyEngine.config.read('uishown'))
  if ProbablyEngine.config.read('uishown') then
    ProbablyEngine.buttons.buttonFrame:Show()
  else
    ProbablyEngine.buttons.buttonFrame:Hide()
  end
end)
ProbablyEngine.command.register_help('toggleui', L('help_toggleui'))

ProbablyEngine.command.register_handler({'help', '?', 'wat'}, function()
  ProbablyEngine.command.print('|cff' .. ProbablyEngine.addonColor .. 'ProbablyEngine |r' .. ProbablyEngine.version)
  for command, help in pairs(ProbablyEngine.command.help) do
    ProbablyEngine.command.print('|cff' .. ProbablyEngine.addonColor .. '/pe ' ..command .. '|r ' .. help)
  end
end)
ProbablyEngine.command.register_help('help', L('help_help'))

ProbablyEngine.command.register_handler({'cycle', 'pew', 'run'}, function()
  ProbablyEngine.cycle(true)
end)
ProbablyEngine.command.register_help('cycle', L('help_cycle'))

ProbablyEngine.command.register_handler({'toggle'}, function()
  ProbablyEngine.buttons.toggle('MasterToggle')
end)
ProbablyEngine.command.register_handler({'enable'}, function()
  ProbablyEngine.buttons.setActive('MasterToggle')
end)
ProbablyEngine.command.register_handler({'disable'}, function()
  ProbablyEngine.buttons.setInactive('MasterToggle')
end)

ProbablyEngine.command.register_help('toggle', L('help_toggle'))

ProbablyEngine.command.register_handler({'cd', 'cooldown', 'cooldowns'}, function()
  ProbablyEngine.buttons.toggle('cooldowns')
end)
ProbablyEngine.command.register_help('cd', L('cooldowns_tooltip'))

ProbablyEngine.command.register_handler({'kick', 'interrupts', 'interrupt', 'silence'}, function()
  ProbablyEngine.buttons.toggle('interrupt')
end)
ProbablyEngine.command.register_help('kick', L('interrupt_tooltip'))


ProbablyEngine.command.register_handler({'aoe', 'multitarget'}, function()
  ProbablyEngine.buttons.toggle('multitarget')
end)
ProbablyEngine.command.register_help('aoe', L('multitarget_tooltip'))


ProbablyEngine.command.register_handler({'al', 'log', 'actionlog'}, function()
  PE_ActionLog:Show()
end)
ProbablyEngine.command.register_help('al', L('help_al'))

ProbablyEngine.command.register_handler({'lag', 'cycletime'}, function()
  PE_CycleLag:Show()
end)

ProbablyEngine.command.register_handler({'turbo', 'godmode'}, function()
  local state = ProbablyEngine.config.toggle('pe_turbo')
  if state then
    ProbablyEngine.print(L('turbo_enable'))
    SetCVar('maxSpellStartRecoveryOffset', 1)
    SetCVar('reducedLagTolerance', 10)
    ProbablyEngine.cycleTime = 10
  else
    ProbablyEngine.print(L('turbo_disable'))
    SetCVar('maxSpellStartRecoveryOffset', 1)
    SetCVar('reducedLagTolerance', 100)
    ProbablyEngine.cycleTime = 100
  end
end)
ProbablyEngine.command.register_help('turbo', L('help_turbo'))

ProbablyEngine.command.register_handler({'bvt'}, function()
  local state = ProbablyEngine.config.toggle('buttonVisualText')
  ProbablyEngine.buttons.resetButtons()
  ProbablyEngine.rotation.add_buttons()
end)
```

*4_3. Enabling + UI*
There are three methods of starting the engine:
1. Click the First Button of the four, on initial load up you should see your specialization displayed inside there. The box should become outlined as if you casted a spell, and if the rotation has an out of combat aspect and you are unlocked, you should see your character cast the relevant spells.

2. /pe toggle - Will turn it on and off, respective to the current status. Macroable

3. /pe enable/disable - Functions similar to toggle, but in one direction only. On and Off, respectively.

Additionally, you can disable the ui with /pe toggleui, however it will retain your current usage status.

*4_4. Toggles and Modifiers*
ProbablyEngine comes out of the box with three modifiers; multitarget, kick/interrupt, and cooldowns. CustomRotations can make their own modifiers, called toggles, and these will appear as boxes next to the three native.
Button 2 - Cooldowns (Hourglass)
Button 3 - Multitarget (Balance Druid's Starfall)
Button 4 - Interrupts (Boot)

*4_5. In / Out of Combat*
ProbablyEngine checks for in/out of combat with the PLAYER_REGEN_ENABLED/DISABLED event.

*4_6. Debugging*
Debugging is relatively simple. You will need a bug-catcher addon for most generic debugging, and there are plenty to choose from on Curse and similar websites. I recommend BugGrabber by Curse user funkydude.

Errors will pop up regarding issues that occur. The most generic one is 


```
[ADDON_ACTION_FORBIDDEN] AddOn 'Probably' tried to call the protected function 'UNKNOWN()'.
!BugGrabber\BugGrabber.lua:589: in function <!BugGrabber\BugGrabber.lua:589>
[C]: ?
[C]: in function `pcall'
Probably\system\protected\generic.lua:10: in function `Generic'
Probably\system\timers\rotation.lua:203: in function `event'
Probably\system\core\timer.lua:16: in function <Probably\system\core\timer.lua:11>

Locals:
nil
```

which means you haven't unlocked yet and ProbablyEngine is enabled. 

If you see something like 


```
38x Probably_Powder\rotation.lua:289: unexpected symbol near '}'
```

there is an error with a custom rotation you have installed, and you should complain loudly and frequently to the developer with much gusto.

Outside generic errors, you can also use /pe al to enable the action log, which lets you see what exactly is going on in the rotation. Cool, huh?

*4_7. Bug Reporting*
All errors should be directed to the Support Forum on OwnedCore. You should get an answer within a day. If you don't, send me a direct message.

If the bug is really really bad, come visit us on our IRC.

*4_8. Custom Rotations*
ProbablyEngine support custom rotatios from third party developers, of which most cases are better than the defaults.
You can find them in the Combat Routines forum on OwnedCore.

A Master List with all routines is located *HERE*

*4_8_1. Installation*
Each rotation installs as it's own addon. So the same method goes as installing Probably:

1. Download the routine from the Combat Routines forum on OwnedCore.
2. Unzip to your addons directory at C:\Program Files (x86)\World of Warcraft\interface\addons
3. Restart or Start your client, confirm enabled in your addons list.
4. ???
5. Profit!

*4_8_2. Confirmation*
Same as with PE, check your addons list. If one shows as out of date, complain to the rotation dev to update his .toc file.

*4_8_3. Profile Selection*
To use a custom rotation, make sure you are in the specialziation the routine is built for and RIGHT CLICK the first button. You should see a dropdown box, and the routine should be under the Custom Rotations sub-heading.

----------


## ImogenOC

*5. Documentation - Preamble*

*5_1. Disclaimer*
Everything from here on out is for the code-saavy among us. It's going to be complicated, long, and boring. Get ready.

Additionally, routine developement is long and exhausting, especially if you make your profile public. You have been warned.

*5_2. Documentation Layout*

Chapter_ID. File/Condition/State
Classifacation
Raw Excerpt
Usage and Explanation
Example (if applicable)

Ergo,

*9_1. dispellable*
Condition


```
ProbablyEngine.condition.register("dispellable", function(target, spell)
    if LibDispellable:CanDispelWith(target, GetSpellID(GetSpellName(spell))) then
    return true
    end
    return false
end)
```

Queries the LibDispellable external-library for spellID specified and spell available to dispel. If true, returns true.

Usage:


```
{ "Purify", "target.dispellable(Chilled)", "target" },
```

*5_3. Support*
For questions relating to documentation, either post in the thread with the chapter_ID and your question, send me a message, or come visit the IRC.

*5_4. Sharing your work*
Interested in sharing your work? Post it in the Combat Routines forum of OwnedCore for quick access to a user base.

----------


## ImogenOC

*6. Custom Rotations - Foreword*
*See 8. for full synopsis*

*6_1. Creation and Programs*
Creation is super simple. Make a folder that contains the following:
rotation.toc
rotation.lua
README.md/txt

And you PREPPED to begin developement. That's the easy part. Now you need a developement enviornment, which in our case is any text editor. You have a number of choices, most people prefer Notepad++, I personally use Sublime due to it's advanced nature.

*6_2. File Hierarchy*
Same as any other addon, your root folder should be located in C:\Program Files (x86)\World of Warcraft\interface\addons\

*6_3. .toc*
Identifies your rotation as an addon, and any dependencies.


```
## Interface: 60100
## Title: Probably
## Notes: Probably
## SavedVariablesPerCharacter: ProbablyEngine_ConfigData
## SavedVariables: ProbablyEngine_RotationData

probably.xml
```

Inteface - Identifies the version
Title - Name of the Addon
Notes - Addon description
SavedVariablePerCharacter - Local config
SavedVariables - Local config

Past that are any dependencies, work as if you are in a root folder. So if you wanted a file named meh.lua in a folder named durr, it would look like this:


```
## Interface: 60100
## Title: Hurr
## Notes: Durr
## Dependencies: Probably

durr/meh.lua
```

*6_4. Hosting Options*
Lots of options here, only one that is guarnteed not to get you heat.
Private Hosting (Your Website)
Dropbox (Bows to DMCA)
Github (Bows to DMCA)
Mega (Bows to DMCA)
AnonFiles
GitLab *(RECOMMENDED)*


*6_5. Support*
Custom rotation support, if you are a user, goes straight to the rotation dev. Otherwise, it goes to the Support Forum on OwnedCore.

----------


## ImogenOC

*7. Probably Source - Explained*

*7_1. PREAMBLE*
This part is incredibly boring, only for those genuinely curious. This explains each file of our source, including what it do and what it don't.

*7_2. external*

*7_2_0. PREAMBLE*
All external libraries used by probablyengine to be probablyengine.

*7_2_1. AceConfig*
AceConfig-3.0 wrapper library. 
Provides an API to register an options table with the config registry, as well as associate it with a slash command.

*7_2_2. AceConsole*
AceConsole-3.0 provides registration facilities for slash commands. 
You can register slash commands to your custom functions and use the `GetArgs` function to parse them to your addons individual needs.

*7_2_3. AceGUI*
AceGUI-3.0 provides access to numerous widgets which can be used to create GUIs. 
AceGUI is used by AceConfigDialog to create the option GUIs, but you can use it by itself to create any custom GUI.

*7_2_4. CallbackHandler*
CallbackHandler is a back-end utility library that makes it easy for a library to fire its events to interested parties. It removes the need for addons to be aware of e.g. AceEvent
.
*7_2_5. DiesalGUI*
Addon Userinterface Framework

*7_2_6. DiesalMenu*
Addon Userinterface Framework

*7_2_7. DiesalStyle*
Addon Userinterface Framework

*7_2_8. DiesalTools*
Addon Userinterface Framework

*7_2_9. LibBoss*
See 7_2_10.

*7_2_10. LibBossIDs*
LibBossIDs-1.0 provides a table that flags mobIDs true if the mob linked to the ID is a boss.

*7_2_11. LibDispellable*
LibDispellable-1.0 aims at helping to test if the player can really dispel an enemy buff or a friend debuff.

*7_2_12. LibDraw*
Developed by doc|brown on fh-wow.com for FireHack. Unused.

*7_2_13. LibRangeCheck*
A library to determine estimated range.

*7_2_14. LibSharedMedia*
Shared handling of media data (fonts, sounds, textures, ...) between addons.

*7_2_15. LibStub*
LibStub is a minimalistic versioning library that allows other libraries to easily register themselves and upgrade. It is meant to be a cross-community library sharing system.

*7_3. interface*

*7_3_0. PREAMBLE*
All the internals that interact with the players

*7_3_1. buttons*
Draws the master toggle and modifiers.

*7_3_2. commands*
Registers commands for the player.

*7_3_3. locale*
Localisation for different languages. Currently supported:
deDE
enES
enGB
enUS
frFR
ruRU
zhCN

If you are interested in helping, send me a message.

*7_3_4. buttons.lua*
Makes the buttons act like buttons, handles custom UI skins.

*7_3_5. config.lua*
Empty.

*7_3_6. custom.lua*
Registers custom rotations and places them in the dropdown box under the first button.

*7_3_7. interface.lua*
Draws the interface.

*7_3_8. locale.lua*
Identifies locale to use.

*7_3_9. log.lua*
Draws the action log.

*7_3_10. manager.lua*
Empty.

*7_3_11. minimap.lua*
Adds the ProbablyEngine Minimap button.

*7_3_12. toggle.lua*
Registers the main toggle.

*7_3_13. tracker.lua*

*7_4. rotations*

*7_4_1. deathknight*
Death Knight rotations folder.
Contains:
blood.lua
frost.lua.
unholy.lua

*7_4_2. druid*
Druid rotations folder.
Contains:
balance.lua
basic_druid.lua
feral.lua
newb_druid.lua
restoration.lua

*7_4_3. hunter*
Hunter rotations folder.
Contains:
basic_hunter.lua
beastmastery.lua
marksmanship.lua
newbhunter.lua
survival.lua

*7_4_4. mage*
Mage rotations folder.
Contains:
arcane.lua
basic_mage.lua
fire.lua
frost.lua
newbmage.lua

*7_4_5. monk*
Monk rotations folder.
Contains:
basic_monk.lua
brewmaster.lua
newbmonk.lua
windwalker.lua

*7_4_6. paladin*
Paladin rotations folder.
Contains:
basic_paladin.lua
newbpaladin.lua
protection.lua
retribution.lua

*7_4_7. priest*
Priest rotations folder.
Contains:
basic_priest.lua
holy.lua
newbpriest.lua
shadow.lua

*7_4_8. rogue*
Rogue (hehe rouge) rotations folder.
Contains:
assassassassination.lua
basic_rogue.lua
combat.lua
newbrogue.lua
subtelty.lua

*7_4_9. shaman*
Shaman rotations folder.
Contains:
basic_shaman.lua
elemental.lua
enhancement.lua
newbshaman.lua
restoration.lua

*7_4_10. shared*
Shared files folder.
Contains:
core.lua

*7_4_11. warlock*
Warlock rotations folder.
Contains:
affliction.lua
basic_warlock.lua
demonology.lua
destruction.lua
newbwarlock.lua

*7_4_12. warrior*
Warrior rotations folder.
Contains:
arms.lua
basic_warrior.lua
fury.lua
newbwarrior.lua
protection.lua

*7_5. system*

*7_5_1. conditions*

*7_5_1_1. core.lua*
Contains all conditionals for probablyengine.

*7_5_1_2. states.lua*
Contains pvp states. For use with english clients only.

*7_5_2. core*
*7_5_2_1. command.lua*
Colors commands and sets their prefix.

*7_5_2_2. condition.lua*
Registers condition syntax.

*7_5_2_3. config.lua*
Config I/O R/W

*7_5_2_4. debug.lua*
Debug printer syntax.

*7_5_2_5. dsl.lua*
ProbablyEngine's heart, and the sassiest file we own.

*7_5_2_6. library.lua*
User loaded library register.

*7_5_2_7. listener.lua*
Event listener

*7_5_2_8. module.lua*
Module syntax register.

*7_5_2_9. overloads.lua*
Localizes and overloads spell indexs, functions, and identifacation.

*7_5_2_10. parser.lua*
ProbablyEngine's parser.

*7_5_2_11. raid.lua*
Raid engine.

*7_5_2_12. rotation.lua*
Rotation engine. Identifies the specializations, syntax for rotations, and functions.

*7_5_2_13. set.lua*
PE keyset.

*7_5_2_14. timeout.lua*
Timer for spells to blacklist.

*7_5_2_15. timer.lua*
ProbablyEngine cycle timer.

*7_5_2_16. tooltip.lua*
Tooltip reader.

*7_5_3. listeners*
Event Listeners. Lots of them.

*7_5_4. modules*

*7_5_4_1. combat_tracker.lua*
Grabs units in combat.

*7_5_4_2. config.lua*
Pings modifier config.

*7_5_4_3. disarm.lua*
Disarm handler.

*7_5_4_4. faceroll.lua*
Faceroll intialize eng engine.

*7_5_4_5. keymanager.lua*
Unused.

*7_5_4_6. pet.lua*
Registers pet as target.

*7_5_4_7. player.lua*
Identifies the player and related variables.

*7_5_4_8. queue.lua*
Spell queue engine.

*7_5_4_9. target.lua*
I never figued it out, you wont either.



```
-- ProbablyEngine Rotations
-- Released under modified BSD, see attached LICENSE.

ProbablyEngine.module.register("target", {

})
```

*7_5_4_10. tooltip.lua*
Reads tooltips, EN client only.

*7_5_4_11. tracker.lua*
Complete unit tracker.

*7_5_5. protected*
Special modifacations for advanced unlockers.

*7_5_5_1. base.lua*
Identifies unlocker and sets function prototypes.

*7_5_5_2. firehack.lua*
FireHack locale.

*7_5_5_3. generic.lua*
Basic unlocker locale.

*7_5_5_4. offspring.lua*
Offspring locale.

*7_5_6. timers*
Computes lag, spell timers, rotation timers, etc.

*7_6. bindings.xml*
Binds toggles.

*7_7. LICENSE*


```
ProbablyEngine license.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the organization nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.
    * Redistribution of this software in source or binary forms shall be free
      of all charges or fees to the recipient of this software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
```

*7_8. probably.lua*
Sets probablyengine's addon details.

*7_9. probably.toc*
Addon identifier.

*7_10. probably.xml*
Total file list.

*7_11. README.md*
MarkUp Readme for Gitlab.

*7_12. version.txt*
Version file, outdated obviously.

----------


## ImogenOC

*8. Rotation Development*

*8_0. Setup Verification*
Only thing you really need to verify here is your .toc
It should look similar to this:


```
## Interface: 50400
## Title: Probably - Powder - A Nuanced Routine
## Notes: ProbablyEngine Custom Subtlety Rogue
## Dependencies: Probably

rotation.lua
ret.lua
```

Following that, the first line should be identical to ProbablyEngine's .toc, located at:
install_location\World of Warcraft\interface\addons\Probably\probably.toc

*8_1. Rotation Formatting*
ProbablyEngine reads from top-down, looking for the first argument with filled conditions that all return true.
Rotation formatting is up to you, but there are some required aspects.
1. Rotation Register


```
ProbablyEngine.rotation.register_custom(SPECIALIZATION_ID, "ROTATION_NAME", {
```

This registers the custom rotation! Everything past this is part of the rotation.
From there, you can set incombat and outcombat sections like this:


```
ProbablyEngine.rotation.register_custom(261, "Powder", {
{ "combatrotation" },
},{
{ "peace rotation" },
})
```

*8_2. Spell Thread*
The basic spell thread goes as


```
 { "Spell", "condition", "target" },
```

That is the BASIC layout for a custom rotation, but you can get far more indepth than that. Utilizing locales, you can tidy up the actual rotation part of your... rotation.



```
local singletarget = { rotation here }
local aoe = { rotation here }
local uh_oh = { uh_oh defensives here }
local ooc = { combat rotation }
local burst = { pew pew }

ProbablyEngine.rotation.register_custom(SPECIALIZATION_ID, "ROTATION_NAME", {
{ uh_oh },
{ "Execute", "target.health <= 20" },
{ burst },
{ aoe },
{ singletarget },
},{
{ ooc },
})
```

*8_3. SpellID vs SpellName*
If you can, use spellID. SpellNames are discouraged due to only support for that language.
e.g. use 
{ "116" },
not
{ "Frostbolt" },

*8_4. Nesting*
Nesting is a fun, time saving feature that can be a little confusing to some people.
By nesting, we can run a whole section under one specific condition to many spells at one time, useful for advanced to simple unlocker rotation splits.



```
{{
	{ "Spell", "Condition", "target" },
	{ "Spell", "Condition", "target" },
	{ "Spell", "Condition", "target" },
}, "final.condition" },
```

e.g. to test for firehack / non firehack rotations



```
{{
	{ "Spell", "Condition", "target" },
	{ "Spell", "Condition", "target" },
	{ "Spell", "Condition", "target" },
}, "player.firehack" },

{{
	{ "Spell", "Condition", "target" },
	{ "Spell", "Condition", "target" },
	{ "Spell", "Condition", "target" },
}, "!player.firehack" },
```

*8_5. Custom Functions*
From here, you can compartmentalize your rotation to make it easier on you. PE also lets you pull local or external functions, like so:



```
ProbablyEngine.library.register('coreHealing', {
  needsHealing = function(percent, count)
    return ProbablyEngine.raid.needsHealing(tonumber(percent)) >= count
  end,
  needsDispelled = function(spell)
    for unit,_ in pairs(ProbablyEngine.raid.roster) do
      if UnitDebuff(unit, spell) then
        ProbablyEngine.dsl.parsedTarget = unit
        return true
      end
    end
  end,
})

local heal = {
{ "Hymn of Healing", "@coreHealing(5,50)" },
}
local singletarget = { rotation here }
local aoe = { rotation here }
local uh_oh = { uh_oh defensives here }
local ooc = { combat rotation }
local burst = { pew pew }

ProbablyEngine.rotation.register_custom(SPECIALIZATION_ID, "ROTATION_NAME", {
{ uh_oh },
{ heal },
{ "Shadow Word: Death", "target.health <= 20" },
{ burst },
{ aoe },
{ singletarget },
},{
{ ooc },
})
```

Registering a function lets you do anything lua and api based, such as utilizing an advanced unlocker's API or a custom condition.

*8_6. Custom Toggles*
Additionally, we can also make our own toggles, like so:


```
function ()
  ProbablyEngine.toggle.create('toggleID', 'Interface\\Icons\\some_icon_name', 'Toggle Name', 'Toggle Description')
  end)
```

From there, you can call it as a condition in a spell thread:


```
{ "Frostbolt", "toggle.frostbolt", "target" },
```

This allows us to make unique toggles for... Anything, really. Just remember, the more toggles, the more buttons. Some people dislike a couple dozen buttons.

Here's a simple, no BS rotation.lua if you need it.


```
ProbablyEngine.rotation.register_custom(SPEC_ID, "ROTATION_NAME", {

  --------------------
  -- Start Rotation --
  --------------------

 { "Spell", "condition" },

  ------------------
  -- End Rotation --
  ------------------

},{

  ---------------
  -- OOC Begin --
  ---------------

  -- Buffs
 { "Spell", "condition" },

  -------------
  -- OOC End --
  -------------

  },
 function ()
  ProbablyEngine.toggle.create('toggleID', 'Interface\\Icons\\some_icon_name', 'Toggle Name', 'Toggle Description')
  end)
```

Icons can be found through wowhead.com, using the search function. Find the icon you want, click on the image, and the icon name will be given in a popup. (e.g. spell_frost_frostbolt02)

*8_7. Bug Testing*
Install your rotation as from 4_8.
Load in, try and use it. If it dosen't work, you'll get an error. If you can't see it, you didn't register right.]The debug feed will go through whatever bug catch addon you have.

----------


## ImogenOC

*9. Conditions*

*9_0. PREAMBLE*
Holy crap this is a long list. Like 140+ long. Very long.
Sections are laid out like this: 
Raw Excerpt:
{code}{/code}

*Usage and Explanation:*

Example:
{code}{/code}

Chapter ID
Raw Excerpt: Contains raw code for the condition
Usage and Explanation: Explains the described.
Example: Shows example usage.

*9_1. disspellable* 
Raw Excerpt:


```
ProbablyEngine.condition.register("dispellable", function(target, spell)
    if LibDispellable:CanDispelWith(target, GetSpellID(GetSpellName(spell))) then
    return true
    end
    return false
end)
```

*Usage and Explanation:*
Usage discouraged, as only EN clients can benefit and the checks are extremely limited. Checks against LibDispellable for inputs given.

Example:


```
{ "Purge", "target.dispellable", "target },
```

*9_2. buff* Condition
Raw Excerpt:


```
ProbablyEngine.condition.register("buff", function(target, spell)
    local buff,_,_,caster = UnitBuff(target, spell)
    if not not buff and (caster == 'player' or caster == 'pet') then
    return true
    end
    return false
end)
```

*Usage and Explanation:*
Checks a buff by name or ID on a given target.

Example:


```
{ "Frostbolt", "target.buff(Arcane Intelligence)", "target" },
```

*9_3. buff.any*
Raw Excerpt:


```
ProbablyEngine.condition.register("buff.any", function(target, spell)
    local buff,_,_,caster = UnitBuff(target, spell, "any")
    if not not buff then
    return true
    end
    return false
end)
```

*Usage and Explanation:*
Checks if the target has any buff.

Example:


```
{ "Frostbolt", "target.buff.any", "target" },
```

*9_4. buff.count*
Raw Excerpt:


```
ProbablyEngine.condition.register("buff.count", function(target, spell)
    local buff,count,_,caster = UnitBuff(target, spell)
    if not not buff and (caster == 'player' or caster == 'pet') then
    return count
    end
    return 0
end)
```

*Usage and Explanation:*
Checks how many stacks of a buff the target has.

Example:


```
{ "Frostbolt", "target.buff.count(Rapid Fire, 2)", "target" },
```

*9_5. debuff*
Raw Excerpt:


```
ProbablyEngine.condition.register("debuff", function(target, spell)
    local debuff,_,_,caster = UnitDebuff(target, spell)
    if not not debuff and (caster == 'player' or caster == 'pet') then
    return true
    end
    return false
end)
```

*Usage and Explanation:*
Checks if a target has a debuff of X name.
Example:


```
{ "Frostbolt", "target.debuff(Frozen)", "target" },
```

*9_6. debuff.any*
Raw Excerpt:


```
ProbablyEngine.condition.register("debuff.any", function(target, spell)
    local debuff,_,_,caster = UnitDebuff(target, spell, "any")
    if not not debuff then
    return true
    end
    return false
end)
```

*Usage and Explanation:*
Checks if a target has ANY debuff.
Example:


```
{ "Frostbolt", "target.debuff.any", "target" },
```

*9_7. debuff.count*
Raw Excerpt:


```
ProbablyEngine.condition.register("debuff.count", function(target, spell)
    local debuff,count,_,caster = UnitDebuff(target, spell)
    if not not debuff and (caster == 'player' or caster == 'pet') then
    return count
    end
    return 0
end)
```

*Usage and Explanation:*

Example:


```
{ "Frostbolt", "target.debuff(DebuffName,2)", "target" },
```

*9_8. debuff.duration*
Raw Excerpt:


```
ProbablyEngine.condition.register("debuff.duration", function(target, spell)
    local debuff,_,expires,caster = UnitDebuff(target, spell)
    if not not debuff and (caster == 'player' or caster == 'pet') then
    return (expires - GetTime())
    end
    return 0
end)
```

*Usage and Explanation:*
Checks a debuff's duration against a comparator.
Example:


```
{ "Frostbolt", "target.debuff(Debuff).duration >= 5", "target" },
```

*9_9. buff.duration*
Raw Excerpt:


```
ProbablyEngine.condition.register("buff.duration", function(target, spell)
    local buff,_,expires,caster = UnitBuff(target, spell)
    if not not buff and (caster == 'player' or caster == 'pet') then
    return (expires - GetTime())
    end
    return 0
end)
```

*Usage and Explanation:*

Example:


```
{ "Frostbolt", "target.debuff(Debuff).duration >= 5", "target" },
```

*9_10. aura.crit*
Raw Excerpt:


```
ProbablyEngine.condition.register("aura.crit", function(target, spell)
    return smartQueryTracker(target, spell, 'crit')
end)
```

*Usage and Explanation:*
SECRET
Example:


```
SECRET
```

*9_11. aura.crits*
Raw Excerpt:


```
ProbablyEngine.condition.register("aura.crits", function(target, spell)
    return smartQueryTracker(target, spell, 'crits')
end)
```

*Usage and Explanation:*
SECRET
Example:


```
SECRET
```

*9_12. aura.avg*
Raw Excerpt:


```
ProbablyEngine.condition.register("aura.avg", function(target, spell)
    return smartQueryTracker(target, spell, 'avg')
end)
```

*Usage and Explanation:*
SECRET
Example:


```
SECRET
```

*9_13. aura.last*
Raw Excerpt:


```
ProbablyEngine.condition.register("aura.last", function(target, spell)
    return smartQueryTracker(target, spell, 'last')
end)
```

*Usage and Explanation:*
SECRET
Example:


```
SECRET
```

*9_14. aura.low*
Raw Excerpt:


```
ProbablyEngine.condition.register("aura.low", function(target, spell)
    return smartQueryTracker(target, spell, 'low')
end)
```

*Usage and Explanation:*
SECRET
Example:


```
SECRET
```

*9_15. aura.high*
Raw Excerpt:


```
ProbablyEngine.condition.register("aura.high", function(target, spell)
    return smartQueryTracker(target, spell, 'high')
end)
```

*Usage and Explanation:*
SECRET
Example:


```
SECRET
```

*9_16. aura.total*
Raw Excerpt:


```
ProbablyEngine.condition.register("aura.total", function(target, spell)
    return smartQueryTracker(target, spell, 'total')
end)
```

*Usage and Explanation:*
SECRET
Example:


```
SECRET
```

*9_17. aura.stacks*
Raw Excerpt:


```
ProbablyEngine.condition.register("aura.stacks", function(target, spell)
    return smartQueryTracker(target, spell, 'stacks')
end)
```

*Usage and Explanation:*
SECRET
Example:


```
SECRET
```

*9_18. aura.time*
Raw Excerpt:


```
ProbablyEngine.condition.register("aura.time", function(target, spell)
    return smartQueryTracker(target, spell, 'time')
end)
```

*Usage and Explanation:*
SECRET
Example:


```
SECRET
```

*9_19. aura.uptime*
Raw Excerpt:


```
ProbablyEngine.condition.register("aura.uptime", function(target, spell)
    return smartQueryTracker(target, spell, 'time') - GetTime()
end)
```

*Usage and Explanation:*
SECRET
Example:


```
SECRET
```

*9_20. stance*
Raw Excerpt:


```
ProbablyEngine.condition.register("stance", function(target, spell)
    return GetShapeshiftForm()
end)
```

*Usage and Explanation:*
Identical to: 9.21, 9.22
Any class
0 = humanoid form

Death Knight
1 = Blood Presence
2 = Frost Presence
3 = Unholy Presence

Druid
1 = Bear/Dire Bear Form
2 = Aquatic Form
3 = Cat Form
4 = Travel Form
5 = Moonkin Form (balance) / Flight Form (resto/feral/guardian)
6 = Flight Form (balance)

Paladin
1 = Seal of Truth
2 = Seal of Righteousness
3 = Seal of Insight - Seal of Justice if retribution
4 = Seal of Insight if retribution

Priest
1 = Chakra: Chastise or Shadowform
2 = Chakra: Sanctuary
3 = Chakra: Serenity
4 = Spirit of Redemption

Rogue
1 = Stealth 
2 = Stealth 
3 = Shadow Dance

Shaman
1 = Ghost Wolf

Warrior
1 = Battle Stance
2 = Defensive Stance
3 = Berserker Stance

Example:


```
{ "Mortal Strike", "player.stance = 3", "target" },
```

*9_21. form*
Raw Excerpt:


```
ProbablyEngine.condition.register("form", function(target, spell)
    return GetShapeshiftForm()
end)
```

*Usage and Explanation:*
Identical to: 9.20, 9.22
Any class
0 = humanoid form

Death Knight
1 = Blood Presence
2 = Frost Presence
3 = Unholy Presence

Druid
1 = Bear/Dire Bear Form
2 = Aquatic Form
3 = Cat Form
4 = Travel Form
5 = Moonkin Form (balance) / Flight Form (resto/feral/guardian)
6 = Flight Form (balance)

Paladin
1 = Seal of Truth
2 = Seal of Righteousness
3 = Seal of Insight - Seal of Justice if retribution
4 = Seal of Insight if retribution

Priest
1 = Chakra: Chastise or Shadowform
2 = Chakra: Sanctuary
3 = Chakra: Serenity
4 = Spirit of Redemption

Rogue
1 = Stealth 
2 = Stealth 
3 = Shadow Dance

Shaman
1 = Ghost Wolf

Warrior
1 = Battle Stance
2 = Defensive Stance
3 = Berserker Stance

Example:


```
{ "Mangle", "player.form = 3", "target" },
```

*9_22. seal*
Raw Excerpt:


```
ProbablyEngine.condition.register("seal", function(target, spell)
    return GetShapeshiftForm()
end)
```

*Usage and Explanation:*
Identical to: 9.20, 9.21
Any class
0 = humanoid form

Death Knight
1 = Blood Presence
2 = Frost Presence
3 = Unholy Presence

Druid
1 = Bear/Dire Bear Form
2 = Aquatic Form
3 = Cat Form
4 = Travel Form
5 = Moonkin Form (balance) / Flight Form (resto/feral/guardian)
6 = Flight Form (balance)

Paladin
1 = Seal of Truth
2 = Seal of Righteousness
3 = Seal of Insight - Seal of Justice if retribution
4 = Seal of Insight if retribution

Priest
1 = Chakra: Chastise or Shadowform
2 = Chakra: Sanctuary
3 = Chakra: Serenity
4 = Spirit of Redemption

Rogue
1 = Stealth 
2 = Stealth 
3 = Shadow Dance

Shaman
1 = Ghost Wolf

Warrior
1 = Battle Stance
2 = Defensive Stance
3 = Berserker Stance
Example:


```
{ "Judgement", "player.seal = 3", "target" },
```

*9_23. focus*
Raw Excerpt:


```
ProbablyEngine.condition.register("focus", function(target, spell)
    return UnitPower(target, SPELL_POWER_FOCUS)
end)
```

*Usage and Explanation:*
Checks how much focus you have against a comparator.
Example:


```
{ "Arcane Shot", "player.focus >= 50", "target" },
```

*9_24. holypower*
Raw Excerpt:


```
ProbablyEngine.condition.register("holypower", function(target, spell)
    return UnitPower(target, SPELL_POWER_HOLY_POWER)
end)
```

*Usage and Explanation:*
Checks how much holypower you have against a comparator.
Example:


```
{ "Flash of Light", "player.holypower = 2", "lowest" },
```

*9_25. shadoworbs*
Raw Excerpt:


```
ProbablyEngine.condition.register("shadoworbs", function(target, spell)
    return UnitPower(target, SPELL_POWER_SHADOW_ORBS)
end)
```

*Usage and Explanation:*
Checks how many shadow orbs you have against a comparator.
Example:


```
{ "Devouring Plague", "player.shadoworbs = 5", "target" },
```

*9_26. energy*
Raw Excerpt:


```
ProbablyEngine.condition.register("energy", function(target, spell)
    return UnitPower(target, SPELL_POWER_ENERGY)
end)
```

*Usage and Explanation:*
Checks how much energy you have against a comparator.
Example:


```
{ "Burst of Speed", "player.energy > 60" },
```

*9_27. solar*
Raw Excerpt:


```
ProbablyEngine.condition.register("solar", function(target, spell)
    return GetEclipseDirection() == 'sun'
end)
```

*Usage and Explanation:*
Use in conjunction with 9_29 and a comparator.
Example:


```
{ "Sunfire", { "player.solar", "player.eclipse >= 20" }, "target" },
```

*9_28. lunar*
Raw Excerpt:


```
ProbablyEngine.condition.register("lunar", function(target, spell)
    return GetEclipseDirection() == 'moon'
end)
```

*Usage and Explanation:*
Use in conjunction with 9_29 and a comparator.
Example:


```
{ "Moonfire", { "player.lunar", "player.eclipse >= 20" }, "target" },
```

*9_29. eclipse*
Raw Excerpt:


```
ProbablyEngine.condition.register("eclipse", function(target, spell)
    return math.abs(UnitPower(target, SPELL_POWER_ECLIPSE))
end)
```

*Usage and Explanation:*
Use in conjuction with 9_27 and 9_28 and a comparator.
Example:


```
{ "Moonfire", { "player.lunar", "player.eclipse >= 20" }, "target" },
```

*9_30. timetomax*
Raw Excerpt:


```
ProbablyEngine.condition.register("timetomax", function(target, spell)
    local max = UnitPowerMax(target)
    local curr = UnitPower(target)
    local regen = select(2, GetPowerRegen(target))
    return (max - curr) * (1.0 / regen)
end)
```

*Usage and Explanation:*
Measures how long it will take your give power to reach maximum.
Example:


```
{ "Evocation", "player.timetomax <= 30" },
```

*9_31. tomax*
Raw Excerpt:


```
ProbablyEngine.condition.register("tomax", function(target, spell)
    return ProbablyEngine.condition["timetomax"](toggle)
end)
```

*Usage and Explanation:*
Alias of 9_30

*9_32. rage*
Raw Excerpt:


```
ProbablyEngine.condition.register("rage", function(target, spell)
    return UnitPower(target, SPELL_POWER_RAGE)
end)
```

*Usage and Explanation:*
Checks how much rage you have against a comparator.
Example:


```
{ "Mortal Strike", "player.rage <= 80", "target" },
```

*9_33. chi*
Raw Excerpt:


```
ProbablyEngine.condition.register("chi", function(target, spell)
    return UnitPower(target, SPELL_POWER_CHI)
end)
```

*Usage and Explanation:*
Checks how much chi you have against a comparator.
Example:


```
{ "Uplift", "player.chi = 2" },
```

*9_34. demonicfury*
Raw Excerpt:


```
ProbablyEngine.condition.register("demonicfury", function(target, spell)
    return UnitPower(target, SPELL_POWER_DEMONIC_FURY)
end)
```

*Usage and Explanation:*
Checks how much demonic fury you have against a comparator.
Example:


```
{ "Metamorphisis", "player.demonicfury >= 600" },
```

*9_35. embers*
Raw Excerpt:


```
ProbablyEngine.condition.register("embers", function(target, spell)
    return UnitPower(target, SPELL_POWER_BURNING_EMBERS, true)
end)
```

*Usage and Explanation:*
Checks how many FULL embers you have against a comparator.
Example:


```
{ "Chaos Bolt", "player.embers >= 2" },
```

*9_36. soulshards*
Raw Excerpt:


```
ProbablyEngine.condition.register("soulshards", function(target, spell)
    return UnitPower(target, SPELL_POWER_SOUL_SHARDS)
end)
```

*Usage and Explanation:*
Checks how many soul shards you have against a comparator.
Example:


```
{ "Haunt", "player.soulshards >= 2", "target" },
```

*9_37. behind*
Raw Excerpt:


```
ProbablyEngine.condition.register("behind", function(target, spell)
    if FireHack then
        return not UnitInfront(target, 'player')
    end
    return ProbablyEngine.module.player.behind
end)
```

*Usage and Explanation:*
Checks, via trial by error, if you are behind a target.
Example:


```
{ "Backstab", "player.behind", "target" },
```

*9_38. infront*
Raw Excerpt:


```
ProbablyEngine.condition.register("infront", function(target, spell)
    if FireHack then
        return UnitInfront(target, 'player')
    end
    return ProbablyEngine.module.player.infront
end)
```

*Usage and Explanation:*
Checks, via trial by error, if you are infront a target.
Example:


```
{ "Gouge", "player.infront", "target" },
```

*9_39. disarmable*
Raw Excerpt:


```
ProbablyEngine.condition.register("disarmable", function(target, spell)
    return ProbablyEngine.module.disarm.check(target)
end)
```

*Usage and Explanation:*
Check if the target is disarmable.
Example:


```
{ "Disarm", "target.disarmable", "target" },
```

*9_40. combopoints*
Raw Excerpt:


```
ProbablyEngine.condition.register("combopoints", function()
    return GetComboPoints('player', 'target')
end)
```

*Usage and Explanation:*
Checks how many combopoints you have against a comparator.
Example:


```
{ "Eviscerate", "player.combopoints = 5", "target" },
```

*9_41. alive*
Raw Excerpt:


```
ProbablyEngine.condition.register("alive", function(target, spell)
    if UnitExists(target) and UnitHealth(target) > 0 then
    return true
    end
    return false
end)
```

*Usage and Explanation:*
Checks if a target is alive.
Example:


```
{ "Flash of Light", "target.alive", "target" },
```

*9_42. dead*
Raw Excerpt:


```
ProbablyEngine.condition.register('dead', function (target)
    return UnitIsDeadOrGhost(target)
end)
```

*Usage and Explanation:*
Checks if the target is dead.
Example:


```
{ "Revive", "target.dead", "target" },
```

*9_43. swimming*
Raw Excerpt:


```
ProbablyEngine.condition.register('swimming', function ()
    return IsSwimming()
end)
```

*Usage and Explanation:*
Checks if you are swimming.
Example:


```
{"Water Walk", "player.swimming", "player" },
```

*9_44. exists*
Raw Excerpt:


```
ProbablyEngine.condition.register("exists", function(target)
    return (UnitExists(target))
end)
```

*Usage and Explanation:*
Checks if something exists. Can be used in many ways.
Example:


```
target.exists, focus.exists, player.spell(spell).exists
```

*9_45. modifier.shift*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.shift", function()
    return IsShiftKeyDown() and GetCurrentKeyBoardFocus() == nil
end)
```

*Usage and Explanation:*
Checks if either shift button is pressed.
Example:


```
{ "Cyclone", "modifier.shift", "focus" },
```

*9_46. modifier.control*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.control", function()
    return IsControlKeyDown() and GetCurrentKeyBoardFocus() == nil
end)
```

*Usage and Explanation:*
Checks if either control button is pressed.
Example:


```
{ "Cyclone", "modifier.control", "focus" },
```

*9_47. modifier.alt*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.alt", function()
    return IsAltKeyDown() and GetCurrentKeyBoardFocus() == nil
end)
```

*Usage and Explanation:*
Checks if either alt button is pressed.
Example:


```
{ "Cyclone", "modifier.alt", "focus" },
```

*9_48. modifier.lshift*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.lshift", function()
    return IsLeftShiftKeyDown() and GetCurrentKeyBoardFocus() == nil
end)
```

*Usage and Explanation:*
Checks if left shift is pressed. Not recommended due to lack of support for macs.
Example:


```
{ "Cyclone", "modifier.lshift", "focus" },
```

*9_49. modifier.lcontrol*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.lcontrol", function()
    return IsLeftControlKeyDown() and GetCurrentKeyBoardFocus() == nil
end)
```

*Usage and Explanation:*
Checks if left control is pressed. Not recommended due to lack of support for macs.
Example:


```
{ "Cyclone", "modifier.lcontrol", "focus" },
```

*9_50. modifier.lalt*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.lalt", function()
    return IsLeftAltKeyDown() and GetCurrentKeyBoardFocus() == nil
end)
```

*Usage and Explanation:*
Checks if left alt is pressed. Not recommended due to lack of support for macs.
Example:


```
{ "Cyclone", "modifier.shift", "focus" },
```

*9_51. modifier.rshift*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.rshift", function()
    return IsRightShiftKeyDown() and GetCurrentKeyBoardFocus() == nil
end)
```

*Usage and Explanation:*
Checks if right shift is pressed. Not recommended due to lack of support for macs.
Example:


```
{ "Cyclone", "modifier.rshift", "focus" },
```

*9_52. modifier.rcontrol*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.rcontrol", function()
    return IsRightControlKeyDown() and GetCurrentKeyBoardFocus() == nil
end)
```

*Usage and Explanation:*
Checks if right control is pressed. Not recommended due to lack of support for macs.
Example:


```
{ "Cyclone", "modifier.rcontrol", "focus" },
```

*9_53. modifier.ralt*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.ralt", function()
    return IsRightAltKeyDown() and GetCurrentKeyBoardFocus() == nil
end)
```

*Usage and Explanation:*
Checks if right alt is pressed. Not recommended due to lack of support for macs.
Example:


```
{ "Cyclone", "modifier.ralt", "focus" },
```

*9_54. modifier.player*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.player", function()
    return UnitIsPlayer("target")
end)
```

*Usage and Explanation:*
Deprecated.

*9_55. classification*
Raw Excerpt:


```
ProbablyEngine.condition.register("classification", function (target, spell)
    if not spell then return false end
    local classification = UnitClassification(target)
    if stringFind(spell, '[%s,]+') then
    for classificationExpected in stringGmatch(spell, '%a+') do
        if classification == stringLower(classificationExpected) then
        return true
        end
    end
    return false
    else
    return UnitClassification(target) == stringLower(spell)
    end
end)
```

*Usage and Explanation:*
Checks what kind of mob target is.
Acceptable inputs are: 
elite - Elite
minus - Minion of another NPC; e.g. does not give experience or reputation.
normal - Normal
rare - Rare
rareelite - Rare-Elite
worldboss - World Boss

Example:


```
{ "Heroism", "targetworldboss)" },
```

*9_56. boss*
Raw Excerpt:


```
ProbablyEngine.condition.register('boss', function (target, spell)
    local classification = UnitClassification(target)
    if spell == 'true' and (classification == 'rareelite' or classification == 'rare') then
    return true
    end
    if classification == 'worldboss' or LibBoss.BossIDs[tonumber(UnitID(target))] then
    return true
    end
    return false
end)
```

*Usage and Explanation:*
Simple check if target is a boss. 
Example:


```
{ "Heroism", "target.boss" },
```

*9_57. id*
Raw Excerpt:


```
ProbablyEngine.condition.register("id", function(target, id)
    local expectedID = tonumber(id)
    if expectedID and UnitID(target) == expectedID then
        return true
    end
    return false
end)
```

*Usage and Explanation:*
Hard check for unitID.
Example:


```
{ "Frostbolt", "target.id = 31144" },
```

*9_58. toggle*
Raw Excerpt:


```
ProbablyEngine.condition.register("toggle", function(toggle)
    return ProbablyEngine.condition["modifier.toggle"](toggle)
end)
```

*Usage and Explanation:*
Alias for 9_59

*9_59. modifier.toggle*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.toggle", function(toggle)
    return ProbablyEngine.config.read('button_states', toggle, false)
end)
```

*Usage and Explanation:*
Checks button state. Not... Really used.

*9_60. modifier.taunt*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.taunt", function()
    if ProbablyEngine.condition["modifier.toggle"]('taunt') then
        if UnitThreatSituation("player", "target") then
            local status = UnitThreatSituation("player", "target")
            return (status < 3)
        end
        return false
    end
    return false
end)
```

*Usage and Explanation:*
Uses if target dosent have max threat status 3 or greater against you.
Example:


```
{ "Taunt", "!target.threat", "target" },
```

*9_61. threat*
Raw Excerpt:


```
ProbablyEngine.condition.register("threat", function(target)
    if UnitThreatSituation("player", target) then
    local isTanking, status, scaledPercent, rawPercent, threatValue = UnitDetailedThreatSituation("player", target)
    return scaledPercent
    end
    return 0
end)
```

*Usage and Explanation:*
Returns a percentage against a comparator.
Example:


```
{ "Taunt", "target.threat <= 80", "target" },
```

*9_62. agro*
Raw Excerpt:


```
ProbablyEngine.condition.register("agro", function(target)
    if UnitThreatSituation(target) and UnitThreatSituation(target) >= 2 then
    return true
    end
    return false
end)
```

*Usage and Explanation:*
Returns true if you start pulling aggro. We spelled it wrong, apparently.
Example:


```
{ "Fade", "target.agro" },
```

*9_63. balance.sun*
Raw Excerpt:


```
ProbablyEngine.condition.register("balance.sun", function()
    local direction = GetEclipseDirection()
    if direction == 'none' or direction == 'sun' then return true end
end)
```

*Usage and Explanation:*
It's like 9_27.

*9_64. balance.moon*
Raw Excerpt:


```
ProbablyEngine.condition.register("balance.moon", function()
    local direction = GetEclipseDirection()
    if direction == 'moon' then return true end
end)
```

*Usage and Explanation:*
It's like 9_28.


*9_64. moving*
Raw Excerpt:


```
ProbablyEngine.condition.register("moving", function(target)
    local speed, _ = GetUnitSpeed(target)
    return speed ~= 0
end)
```

*Usage and Explanation:*
Checks if the target is moving.
Example:


```
{ "Sprint", "player.moving },
```

*9_65. lastmoved*
Raw Excerpt:


```
local movingCache = { }

ProbablyEngine.condition.register("lastmoved", function(target)
    if target == 'player' then
        if not ProbablyEngine.module.player.moving then
            return GetTime() - ProbablyEngine.module.player.movingTime
        end
        return false
    else
        if UnitExists(target) then
            local guid = UnitGUID(target)
            if movingCache[guid] then
                local moving = (GetUnitSpeed(target) > 0)
                if not movingCache[guid].moving and moving then
                    movingCache[guid].last = GetTime()
                    movingCache[guid].moving = true
                    return false
                elseif moving then
                    return false
                elseif not moving then
                    movingCache[guid].moving = false
                    return GetTime() - movingCache[guid].last
                end
            else
                movingCache[guid] = { }
                movingCache[guid].last = GetTime()
                movingCache[guid].moving = (GetUnitSpeed(target) > 0)
                return false
            end
        end
        return false
    end
end)
```

*Usage and Explanation:*
Checks the last time target moved against a comparator.
Example:


```
{ "Frostbolt", "player.lastmoved > 3", "target" },
```

*9_66. movingfor*
Raw Excerpt:


```
ProbablyEngine.condition.register("movingfor", function(target)
    if target == 'player' then
        if ProbablyEngine.module.player.moving then
            return GetTime() - ProbablyEngine.module.player.movingTime
        end
        return false
    else
        if UnitExists(target) then
            local guid = UnitGUID(target)
            if movingCache[guid] then
                local moving = (GetUnitSpeed(target) > 0)
                if not movingCache[guid].moving then
                    movingCache[guid].last = GetTime()
                    movingCache[guid].moving = (GetUnitSpeed(target) > 0)
                    return false
                elseif moving then
                    return GetTime() - movingCache[guid].last
                elseif not moving then
                    movingCache[guid].moving = false
                    return false
                end
            else
                movingCache[guid] = { }
                movingCache[guid].last = GetTime()
                movingCache[guid].moving = (GetUnitSpeed(target) > 0)
                return false
            end
        end
        return false
    end
end)
```

*Usage and Explanation:*
Checks how long you have been moving against a comparator.
Example:


```
{ "Burst of Speed", "player.movingfor > 3", "target" },
```

*9_67. ruinicpower*
Raw Excerpt:


```
ProbablyEngine.condition.register("runicpower", function(target, spell)
    return UnitPower(target, SPELL_POWER_RUNIC_POWER)
end)
```

*Usage and Explanation:*
Checks how much runicpower target has against a comparator.
Example:


```
{ "Anti-Magic Shell", "player.runicpower <= 60" },
```

*9_68. runes.count*
Raw Excerpt:


```
ProbablyEngine.condition.register("runes.count", function(target, rune)
    local rune = string.lower(rune)
    -- 12 b, 34 f, 56 u
    runes_t[1], runes_t[2], runes_t[3], runes_t[4], runes_c[1], runes_c[2], runes_c[3], runes_c[4] = 0,0,0,0,0,0,0,0
    for i=1, 6 do
        local _, _, c = GetRuneCooldown(i)
        local t = GetRuneType(i)
        runes_t[t] = runes_t[t] + 1
        if c then
            runes_c[t] = runes_c[t] + 1
        end
    end
    if rune == 'frost' then
        return runes_c[3] + runes_c[4]
    elseif rune == 'blood' then
        return runes_c[1] + runes_c[4]
    elseif rune == 'unholy' then
        return runes_c[2] + runes_c[4]
    elseif rune == 'death' then
        return runes_c[4]
    end
    return 0
end)
```

*Usage and Explanation:*
Returns count of X rune.
Example:


```
{ "Death Strike", "runes.count(death,2)", "target" },
```

*9_69. runes.frac*
Raw Excerpt:


```
ProbablyEngine.condition.register("runes.frac", function(target, rune)
    local rune = string.lower(rune)
    -- 12 b, 34 f, 56 u
    runes_t[1], runes_t[2], runes_t[3], runes_t[4], runes_c[1], runes_c[2], runes_c[3], runes_c[4] = 0,0,0,0,0,0,0,0
    for i=1, 6 do
        local r, d, c = GetRuneCooldown(i)
        local frac = 1-(r/d)
        local t = GetRuneType(i)
        runes_t[t] = runes_t[t] + 1
        if c then
            runes_c[t] = runes_c[t] + frac
        end
    end
    if rune == 'frost' then
        return runes_c[3] + runes_c[4]
    elseif rune == 'blood' then
        return runes_c[1] + runes_c[4]
    elseif rune == 'unholy' then
        return runes_c[2] + runes_c[4]
    elseif rune == 'death' then
        return runes_c[4]
    end
    return 0
end)
```

*Usage and Explanation:*
I honestly have no clue what the hell this does. We've had it forever, and I've never seen it used.

*9_70. runes.depleted*
Raw Excerpt:


```
ProbablyEngine.condition.register("runes.depleted", function(target, spell)
    local regeneration_threshold = 1
    for i=1,6,2 do
        local start, duration, runeReady = GetRuneCooldown(i)
        local start2, duration2, runeReady2 = GetRuneCooldown(i+1)
        if not runeReady and not runeReady2 and duration > 0 and duration2 > 0 and start > 0 and start2 > 0 then
            if (start-GetTime()+duration)>=regeneration_threshold and (start2-GetTime()+duration2)>=regeneration_threshold then
                return true
            end
        end
    end
    return false
end)
```

*Usage and Explanation:*
Checks how many... Nevermind, I don't know. Same as before, no body uses this and I don't have a clue what it does.

*9_71. runes*
Raw Excerpt:


```
ProbablyEngine.condition.register("runes", function(target, rune)
    return ProbablyEngine.condition["runes.count"](target, rune)
end)
```

*Usage and Explanation:*
Alias for 9_68

Example:


```
{ "Death Strike", "runes.count(death,2)", "target" },
```

*9_72. health*
Raw Excerpt:


```
ProbablyEngine.condition.register("health", function(target)
    if UnitExists(target) then
        return math.floor((UnitHealth(target) / UnitHealthMax(target)) * 100)
    end
    return 0
end)
```

*Usage and Explanation:*
Checks a target's health against a comparator.

Example:


```
{ "Execute", "target.health <= 30", "target" },
```

*9_73. health.actual*
Raw Excerpt:


```
ProbablyEngine.condition.register("health.actual", function(target)
    return UnitHealth(target)
end)
```

*Usage and Explanation:*
Returns the actual HP of the target against a comparator. 
Example:


```
{ "Execute", "target.health <= 20000", "target" },
```

*9_74. health.max*
Raw Excerpt:


```
ProbablyEngine.condition.register("health.max", function(target)
    return UnitHealthMax(target)
end)
```

*Usage and Explanation:*
Checks unit max health against a comparator.
Example:


```
{ "Polymorph", "target.maxhealth > 9000", "target" },
```

*9_75. mana*
Raw Excerpt:


```
ProbablyEngine.condition.register("mana", function(target, spell)
    if UnitExists(target) then
        return math.floor((UnitMana(target) / UnitManaMax(target)) * 100)
    end
    return 0
end)
```

*Usage and Explanation:*

Example:
*9_76. raid.health*
Raw Excerpt:


```
ProbablyEngine.condition.register("raid.health", function()
    return ProbablyEngine.raid.raidPercent()
end)
```

*Usage and Explanation:*
Returns the avg raid health against a comparator.
Example:


```
{ "Tranquility", "raid.health <= 60" },
```

*9_77. modifier.multitarget*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.multitarget", function()
    return ProbablyEngine.condition["modifier.toggle"]('multitarget')
end)
```

*Usage and Explanation:*
Simple bool return if multitarget is enabled.
Example:


```
{ "Mind Sear", "modifier.multitarget", "target" },
```

*9_78. modifier.cooldowns*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.cooldowns", function()
    return ProbablyEngine.condition["modifier.toggle"]('cooldowns')
end)
```

*Usage and Explanation:*
Simple bool return if cooldowns is enabled.
Example:


```
{ "Heroism", "modifier.cooldown" },
```

*9_79. modifier.cooldown*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.cooldown", function()
    return ProbablyEngine.condition["modifier.toggle"]('cooldowns')
end)
```

*Usage and Explanation:*
Simple bool return if cooldowns is enabled.
Example:


```
{ "Heroism", "modifier.cooldown" },
```

*9_80. modifier.interrupts*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.interrupts", function()
    if ProbablyEngine.condition["modifier.toggle"]('interrupt') then
    local stop = ProbablyEngine.condition["casting"]('target')
    if stop then StopCast() end
    return stop
    end
    return false
end)
```

*Usage and Explanation:*
Simple bool check if interrupts is enabled, and if target is casting.
Example:


```
{ "Kick", "modifier.interrupts", "target" },
```

*9_81. modifier.interrupt*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.interrupt", function()
    if ProbablyEngine.condition["modifier.toggle"]('interrupt') then
    return ProbablyEngine.condition["casting"]('target')
    end
    return false
end)
```

*Usage and Explanation:*
Identical to 9_80.

*9_82. modifier.last*
Raw Excerpt:


```
local lastDepWarn = false

ProbablyEngine.condition.register("modifier.last", function(target, spell)
    if not lastDepWarn then
        ProbablyEngine.print('modifier.last has been deprecated, please use lastcast')
        lastDepWarn = true
    end
    return ProbablyEngine.parser.lastCast == GetSpellName(spell)
end)
```

*Usage and Explanation:*
Deprecated, see 9_83

*9_83. lastcast*
Raw Excerpt:


```
ProbablyEngine.condition.register("lastcast", function(spell, arg)
    if arg then spell = arg end
    return ProbablyEngine.parser.lastCast == GetSpellName(spell)
end)
```

*Usage and Explanation:*
Returns last casted spell.
Example:


```
{ "Frostbolt", "player.lastcast(Deep Freeze)", "target" },
```

*9_84. enchant.mainhand*
Raw Excerpt:


```
ProbablyEngine.condition.register("enchant.mainhand", function()
    return (select(1, GetWeaponEnchantInfo()) == 1)
end)
```

*Usage and Explanation:*
Checks if mainhand has a weapon enchant.
Example:


```
{ "Flametongue Weapon", "!enchant.mainhand" },
```

*9_85. enchant.offhand*
Raw Excerpt:


```
ProbablyEngine.condition.register("enchant.offhand", function()
    return (select(4, GetWeaponEnchantInfo()) == 1)
end)
```

*Usage and Explanation:*
Offhand, identical to mainhand.

*9_86. totem*
Raw Excerpt:


```
ProbablyEngine.condition.register("totem", function(target, totem)
    for index = 1, 4 do
        local _, totemName, startTime, duration = GetTotemInfo(index)
        if totemName == GetSpellName(totem) then
            return true
        end
    end
    return false
end)
```

*Usage and Explanation:*
Returns if a totem of X name exists.
Example:


```
{ "Storm Elemental Totem", "!player.totem(Storm Elemental Totem)" },
```

*9_87. totem.duration*
Raw Excerpt:


```
ProbablyEngine.condition.register("totem.duration", function(target, totem)
    for index = 1, 4 do
    local _, totemName, startTime, duration = GetTotemInfo(index)
    if totemName == GetSpellName(totem) then
        return floor(startTime + duration - GetTime())
    end
    end
    return 0
end)
```

*Usage and Explanation:*
Returns totem duration against comparator.

Example:


```
{ "Searing Totem", "player.totem(Searing Totem).duration <= 5
```

*9_88. mushrooms*
Raw Excerpt:


```
ProbablyEngine.condition.register("mushrooms", function ()
    local count = 0
    for slot = 1, 3 do
    if GetTotemInfo(slot) then
        count = count + 1 end
    end
    return count
end)
```

*Usage and Explanation:*
Very deprecated.

*9_89. casting.time*
Raw Excerpt:


```
ProbablyEngine.condition.register('casting.time', function(target, spell)
    local name, startTime, endTime = checkCasting(target)
    if not endTime or not startTime then return false end
    if name then return (endTime - startTime) / 1000 end
    return false
end)
```

*Usage and Explanation:*
Returns how long it will take to cast a spell.
Example:


```
{ "Heroism", "target.casting >= 1" },
```

*9_90. casting.delta*
Raw Excerpt:


```
ProbablyEngine.condition.register('casting.delta', function(target, spell)
    local name, startTime, endTime, notInterruptible = checkCasting(target)
    if not endTime or not startTime then return false end
    if name and not notInterruptible then
    local castLength = (endTime - startTime) / 1000
    local secondsLeft = endTime / 1000  - GetTime()
    return secondsLeft, castLength
    end
    return false
end)
```

*Usage and Explanation:*
Deprecated.

*9_91. casting.percent*
Raw Excerpt:


```
ProbablyEngine.condition.register('casting.percent', function(target, spell)
    local name, startTime, endTime, notInterruptible = checkCasting(target)
    if name and not notInterruptible then
    local castLength = (endTime - startTime) / 1000
    local secondsLeft = endTime / 1000  - GetTime()
    return ((secondsLeft/castLength)*100)
    end
    return false
end)
```

*Usage and Explanation:*
Compares cast percentage against comparator.
Example:


```
{ "Kick", "target.casting.percent >= 80" },
```

*9_92. channeling and casting*
Raw Excerpt:


```
ProbablyEngine.condition.register('channeling', function (target, spell)
    return checkChanneling(target)
end)
```



```
ProbablyEngine.condition.register("casting", function(target, spell)
    local castName,_,_,_,_,endTime,_,_,notInterruptibleCast = UnitCastingInfo(target)
    local channelName,_,_,_,_,endTime,_,notInterruptibleChannel = UnitChannelInfo(target)
    spell = GetSpellName(spell)
    if (castName == spell or channelName == spell) and not not spell then
    return true
    elseif notInterruptibleCast == false or notInterruptibleChannel == false then
    return true
    end
    return false
end)
```

*Usage and Explanation:*
Checks if the target is casting or channeling, respectively. Can be used with spell ID
Example:


```
{ "Kick", "target.casting(Frostbolt)", "target" },
{ "Kick", "target.channeling(Penance)", "target" },
```

*9_93. interruptsat*
Raw Excerpt:


```
ProbablyEngine.condition.register('interruptsAt', function (target, spell)
    if ProbablyEngine.condition['modifier.toggle']('interrupt') then
    if UnitName('player') == UnitName(target) then return false end
    local stopAt = tonumber(spell) or 95
    local secondsLeft, castLength = ProbablyEngine.condition['casting.delta'](target)
    if secondsLeft and 100 - (secondsLeft / castLength * 100) > stopAt then
        StopCast()
        return true
    end
    end
    return false
end)
```

*Usage and Explanation:*
Returns cast percentage against comparator & interrupts enabled.
Example:


```
{ "Kick", "target.interruptsat >= 80", "target" },
```

*9_94. interruptat*
Raw Excerpt:


```
ProbablyEngine.condition.register('interruptAt', function (target, spell)
    if ProbablyEngine.condition['modifier.toggle']('interrupt') then
    if UnitName('player') == UnitName(target) then return false end
    local stopAt = tonumber(spell) or 95
    local secondsLeft, castLength = ProbablyEngine.condition['casting.delta'](target)
    if secondsLeft and 100 - (secondsLeft / castLength * 100) > stopAt then
        return true
    end
    end
    return false
end)
```

*Usage and Explanation:*
Identical to 9_93

*9_95. spell.cooldown*
Raw Excerpt:


```
ProbablyEngine.condition.register("spell.cooldown", function(target, spell)
    local start, duration, enabled = GetSpellCooldown(spell)
    if not start then return false end
    if start ~= 0 then
    return (start + duration - GetTime())
    end
    return 0
end)
```

*Usage and Explanation:*
Returns if a spell is on cooldown, bool.
Example:


```
{ "Preparation", "player.spell(Vanish).cooldown" },
```

*9_96. spell.recharge*
Raw Excerpt:


```
ProbablyEngine.condition.register("spell.recharge", function(target, spell)
    local charges, maxCharges, start, duration = GetSpellCharges(spell)
    if not start then return false end
    if start ~= 0 then
    return (start + duration - GetTime())
    end
    return 0
end)
```

*Usage and Explanation:*
Returns how long it will take a charge spell to recharge against a comparator.
Example:


```
{ "Spell", "player.spell(Spell).recharge >= 10" },
```

*9_97. spell.usable*
Raw Excerpt:


```
ProbablyEngine.condition.register("spell.usable", function(target, spell)
    return (IsUsableSpell(spell) ~= nil)
end)
```

*Usage and Explanation:*
Bool check if a spell is usable.
Example:


```
{ "Vanish", "player.spell(Vanish).usable" },
```

*9_98. spell.exists*
Raw Excerpt:


```
ProbablyEngine.condition.register("spell.exists", function(target, spell)
    if GetSpellBookIndex(spell) then
    return true
    end
    return false
end)
```

*Usage and Explanation:*
Returns if a spell in a book exists. Can be used to check if a talent exists too.
Example:


```
{ "Frostbolt", "player.spell(frostbolt).exists" },
```

*9_99. spell.casted*
Raw Excerpt:


```
ProbablyEngine.condition.register("spell.casted", function(target, spell)
    return ProbablyEngine.module.player.casted(GetSpellName(spell))
end)
```

*Usage and Explanation:*
The module required dosent exist.

*9_100. spell.charges*
Raw Excerpt:


```
ProbablyEngine.condition.register("spell.charges", function(target, spell)
    return select(1, GetSpellCharges(spell))
end)
```

*Usage and Explanation:*
Returns charges remaining against a comparator
Example:


```
{ "Spell", "player.spell(spell).charges >= 1" },
```

*9_101. spell.cd*
Raw Excerpt:


```
ProbablyEngine.condition.register("spell.cd", function(target, spell)
    return ProbablyEngine.condition["spell.cooldown"](target, spell)
end)
```

*Usage and Explanation:*
Alias for 9_95

*9_102. spell.range*
Raw Excerpt:


```
ProbablyEngine.condition.register("spell.range", function(target, spell)
    local spellIndex, spellBook = GetSpellBookIndex(spell)
    if not spellIndex then return false end
    return spellIndex and IsSpellInRange(spellIndex, spellBook, target)
end)
```

*Usage and Explanation:*
Returns bool if spell is in range.

Example:


```
{ "Arcane Shot", "player.spell(Arcane Shot).range" },
```

*9_103. talent*
Raw Excerpt:


```
ProbablyEngine.condition.register("talent", function(args)
    local row, col = strsplit(",", args, 2)
    return hasTalent(tonumber(row), tonumber(col))
end)
```

*Usage and Explanation:*
Checks row and column if talent is selected. Harder version of spell.exists.
Example:


```
{ "Talent", "player.talent(2,3)", "target" },
```

*9_104. friend*
Raw Excerpt:


```
ProbablyEngine.condition.register("friend", function(target, spell)
    return ( UnitCanAttack("player", target) ~= 1 )
end)
```

*Usage and Explanation:*
Checks bool if target is friendly.
Example:


```
{ "Revive", { "target.dead", "target.friendly" }, "target" },
```

*9_105. enemy*
Raw Excerpt:


```
ProbablyEngine.condition.register("enemy", function(target, spell)
    return ( UnitCanAttack("player", target) )
end)
```

*Usage and Explanation:*
Opposite of 9_104, returns bool if you can attack target.
Example:


```
{ "Arcane Shot", "target.enemy", "target" },
```

*9_106. glyph*
Raw Excerpt:


```
ProbablyEngine.condition.register("glyph", function(target, spell)
    local spellId = tonumber(spell)
    local glyphName, glyphId

    for i = 1, 6 do
    glyphId = select(4, GetGlyphSocketInfo(i))
    if glyphId then
        if spellId then
        if select(4, GetGlyphSocketInfo(i)) == spellId then
            return true
        end
        else
        glyphName = GetSpellName(glyphId)
        if glyphName:find(spell) then
            return true
        end
        end
    end
    end
    return false
end)
```

*Usage and Explanation:*
Deprecated, use spell.exists until we find a workaround.

*9_107. range*
Raw Excerpt:


```
ProbablyEngine.condition.register("range", function(target)
    return ProbablyEngine.condition["distance"](target)
end)
```

*Usage and Explanation:*
Alias for 9_108

*9_108. distance*
Raw Excerpt:


```
ProbablyEngine.condition.register("distance", function(target)
    if Distance then
        return math.floor(Distance(target, 'player'))
    else -- fall back to libRangeCheck
        local minRange, maxRange = rangeCheck:GetRange(target)
        return maxRange or minRange
    end
end)
```

*Usage and Explanation:*
Returns estimated distance against comparator unless using advanced unlocker.
Example:


```
{ "Charge", "target.range >= 15", "target" },
```

*9_109. level*
Raw Excerpt:


```
ProbablyEngine.condition.register("level", function(target, range)
    return UnitLevel(target)
end)
```

*Usage and Explanation:*
Returns integer against comparator for target level.
Example:


```
{ "Divine Shield", "target.level > 100" },
```

*9_110. combat*
Raw Excerpt:


```
ProbablyEngine.condition.register("combat", function(target, range)
    return UnitAffectingCombat(target)
end)
```

*Usage and Explanation:*
Returns bool if target is in combat.

Example:


```
{ "Polymorph", "target.combat", "target" },
```

*9_111. time*
Raw Excerpt:


```
ProbablyEngine.condition.register("time", function(target, range)
    if ProbablyEngine.module.player.combatTime then
        return GetTime() - ProbablyEngine.module.player.combatTime
    end
    return false
end)
```

*Usage and Explanation:*
Returns time in combat against comparator in seconds..
Example:


```
{ "Heroism", "player.time >= 600" },
```

*9_112. deathin*
Raw Excerpt:


```
local deathTrack = { }
ProbablyEngine.condition.register("deathin", function(target, range)
    local guid = UnitGUID(target)
    if deathTrack[target] and deathTrack[target].guid == guid then
        local start = deathTrack[target].time
        local currentHP = UnitHealth(target)
        local maxHP = deathTrack[target].start
        local diff = maxHP - currentHP
        local dura = GetTime() - start
        local hpps = diff / dura
        local death = currentHP / hpps
        if death == math.huge then
            return 8675309
        elseif death < 0 then
            return 0
        else
            return death
        end
    elseif deathTrack[target] then
        table.empty(deathTrack[target])
    else
        deathTrack[target] = { }
    end
    deathTrack[target].guid = guid
    deathTrack[target].time = GetTime()
    deathTrack[target].start = UnitHealth(target)
    return 8675309
end)
```

*Usage and Explanation:*
Returns estimated target time to death against comparator.
Example:


```
{ "Berserk", "target.deathin <= 20" },
```

*9_113. ttd*
Raw Excerpt:


```
ProbablyEngine.condition.register("ttd", function(target, range)
    return ProbablyEngine.condition["deathin"](target)
end)
```

*Usage and Explanation:*
Alias to 9_112

*9_114. role*
Raw Excerpt:


```
ProbablyEngine.condition.register("role", function(target, role)
    role = role:upper()

    local damageAliases = { "DAMAGE", "DPS", "DEEPS" }

    local targetRole = UnitGroupRolesAssigned(target)
    if targetRole == role then return true
    elseif role:find("HEAL") and targetRole == "HEALER" then return true
    else
    for i = 1, #damageAliases do
        if role == damageAliases[i] then return true end
    end
    end

    return false
end)
```

*Usage and Explanation:*
Returns target's in party/raid role.
Example:


```
{ "Fear Ward", "target.role(Healer)", "target" },
```

*9_115. name*
Raw Excerpt:


```
ProbablyEngine.condition.register("name", function (target, expectedName)
    return UnitExists(target) and UnitName(target):lower():find(expectedName:lower()) ~= nil
end)
```

*Usage and Explanation:*
Hard check for unit name.
Example:


```
{ "Heroism", "target.name(Aeonaxx)" },
```

*9_116. modifier.group*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.party", function()
    return IsInGroup()
end)
```

*Usage and Explanation:*
Returns bool if you are in a group
Example:


```
{ "Spell", "player.party" },
```

*9_117. modifier.raid*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.raid", function()
    return IsInRaid()
end)
```

*Usage and Explanation:*
Returns bool if you are in raid.
Example:


```
{ "Spell", "player.raid", "target" },
```

*9_118. party*
Raw Excerpt:


```
ProbablyEngine.condition.register("party", function(target)
    return UnitInParty(target)
end)
```

*Usage and Explanation:*
Returns bool if target is in a party.
Example:


```
{ "Spell", "target.party" },
```

*9_119. raid*
Raw Excerpt:


```
ProbablyEngine.condition.register("raid", function(target)
    return UnitInRaid(target)
end)
```

*Usage and Explanation:*
Returns bool if target is in raid.
Example:


```
{ "Spell", "target.raid" },
```

*9_120. modifier.members*
Raw Excerpt:


```
ProbablyEngine.condition.register("modifier.members", function()
    return (GetNumGroupMembers() or 0)
end)
```

*Usage and Explanation:*
Returns integer against comparator for group members.
Example:


```
{ "Uplift", "modifier.members >= 10" },
```

*9_121. creatureType*
Raw Excerpt:


```
ProbablyEngine.condition.register("creatureType", function (target, expectedType)
    return UnitCreatureType(target) == expectedType
end)
```

*Usage and Explanation:*
Returns creature type against input. Accepted inputs are: 
* Beast
* Dragonkin
* Demon
* Elemental
* Giant
* Undead
* Humanoid
* Critter
* Mechanical
* Not specified
* Totem
* Non-combat Pet
* Gas Cloud
Example:


```
{ "Shadow Word: Pain", "target.creaturetype(Totem)", "target" },
```

*9_122. class*
Raw Excerpt:


```
ProbablyEngine.condition.register("class", function (target, expectedClass)
    local class, _, classID = UnitClass(target)

    if tonumber(expectedClass) then
    return tonumber(expectedClass) == classID
    else
    return expectedClass == class
    end
end)
```

*Usage and Explanation:*
Returns integer against input. Accepted input:
None = 0
Warrior = 1
Paladin = 2
Hunter = 3
Rogue = 4
Priest = 5
DeathKnight = 6
Shaman = 7
Mage = 8
Warlock = 9
Monk = 10
Druid = 11
Example:


```
{ "Polymorph", "!target.class(11)", "target" },
```

*9_123. falling*
Raw Excerpt:


```
ProbablyEngine.condition.register("falling", function()
    return IsFalling()
end)
```

*Usage and Explanation:*
Returns bool if target is falling.
Example:


```
{ "Slow Fall", "player.falling" },
```

*9_124. timeout*
Raw Excerpt:


```
ProbablyEngine.condition.register("timeout", function(args)
    local name, time = strsplit(",", args, 2)
    if tonumber(time) then
        if ProbablyEngine.timeout.check(name) then
            return false
        end
        ProbablyEngine.timeout.set(name, tonumber(time))
        return true
    end
    return false
end)
```

*Usage and Explanation:*
Blacklists spell for input time since last cast.
Example:


```
{ "Frostbolt", "player.spell(Frostbolt).timeout >= 3" },
```

*9_125. hashero*
Raw Excerpt:


```
local heroismBuffs = { 32182, 90355, 80353, 2825, 146555 }

ProbablyEngine.condition.register("hashero", function(unit, spell)
    for i = 1, #heroismBuffs do
    if UnitBuff('player', GetSpellName(heroismBuffs[i])) then
        return true
    end
    end
    return false
end)
```

*Usage and Explanation:*
Simple buff check for heroism-esque spells.
Example:


```
{ "Heroism", "!player.hashero" },
```

*9_126. buffs.stats*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.stats", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(1) ~= nil)
end)
```

*Usage and Explanation:*
Checks if target has a stats buff.
Example:


```
{ "Spell", "!target.buffs.stats", "target" },
```

*9_127. buffs.stamina*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.stamina", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(2) ~= nil)
end)
```

*Usage and Explanation:*
Checks if target has a stamina buff.
Example:


```
{ "Spell", "!target.buffs.stamina", "target" },
```

*9_128. buffs.attackpower*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.attackpower", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(3) ~= nil)
end)
```

*Usage and Explanation:*
Checks if target has an attackpower buff.
Example:


```
{ "Spell", "!target.buffs.attackpower", "target" },
```

*9_129. buffs.attackspeed*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.attackspeed", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(4) ~= nil)
end)
```

*Usage and Explanation:*
Checks if target has an attackspeed buff.
Example:


```
{ "Spell", "!target.buffs.attackspeed", "target" },
```

*9_130. buffs.haste*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.haste", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(4) ~= nil)
end)
```

*Usage and Explanation:*
Checks if target has a haste buff.
Example:


```
{ "Spell", "!target.buffs.haste", "target" },
```

*9_131. buffs.spellpower*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.spellpower", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(5) ~= nil)
end)
```

*Usage and Explanation:*
Checks if target has a spellpower buff.
Example:


```
{ "Spell", "!target.buffs.spellpower", "target" },
```

*9_132. buffs.crit*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.crit", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(6) ~= nil)
end)
```

*Usage and Explanation:*
Checks if target has a crit buff.
Example:


```
{ "Spell", "!target.buffs.crit", "target" },
```

*9_133. buffs.critical/criticalstrike*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.critical", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(6) ~= nil)
end)
```

*Usage and Explanation:*
Alias to 9_133

*9_134. buffs.mastery*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.mastery", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(7) ~= nil)
end)
```

*Usage and Explanation:*
Checks if target has a mastery buff.
Example:


```
{ "Spell", "!target.buffs.mastery", "target" },
```

*9_135. buffs.multistrike*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.multistrike", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(8) ~= nil)
end)
```

*Usage and Explanation:*
Checks if target has a multistrike buff.
Example:


```
{ "Spell", "!target.buffs.multistrike", "target" },
```

*9_136. buffs.multi*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.multi", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(8) ~= nil)
end)
```

*Usage and Explanation:*
Alias to 9_135

*9_137. buffs.vers*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.vers", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(9) ~= nil)
end)
```

*Usage and Explanation:*
Checks if target has a versatility buff.
Example:


```
{ "Spell", "!target.buffs.vers", "target" },
```

*9_138. buffs.versatility*
Raw Excerpt:


```
ProbablyEngine.condition.register("buffs.versatility", function(unit, _)
    return (GetRaidBuffTrayAuraInfo(9) ~= nil)
end)
```

*Usage and Explanation:*
Alias for 9_137

*9_139. charmed*
Raw Excerpt:


```
ProbablyEngine.condition.register("charmed", function(unit, _)
    return (UnitIsCharmed(unit) == true)
end)
```

*Usage and Explanation:*
Bool check if target is charmed.
Example:


```
{ "Ice Lance", "target.charmed", "target" },
```

*9_140. vengeance*
Raw Excerpt:


```
ProbablyEngine.condition.register("vengeance", function(unit, spell)
    local vengeance = select(15, _G['UnitBuff']("player", GetSpellName(132365)))
    if not vengeance then
        return 0
    end
    if spell then
        return vengeance
    end
    return vengeance / UnitHealthMax("player") * 100
end)
```

*Usage and Explanation:*
Returns vegeance stack against comparator + integer.
Example:


```
{ "Spell", "player.vengeance >= 400" },
```

*9_141. area.enemies*
Raw Excerpt:


```
ProbablyEngine.condition.register("area.enemies", function(unit, distance)
    if UnitsAroundUnit then
        local total = UnitsAroundUnit(unit, tonumber(distance))
        return total
    end
    return 0
end)
```

*Usage and Explanation:*
Utilizes smart unlocker to calculate enemies around target.
Example:


```
{ "Spell", "target.area(10).enemies >= 10" },
```

*9_142. area.friendly*
Raw Excerpt:


```
ProbablyEngine.condition.register("area.friendly", function(unit, distance)
    if FriendlyUnitsAroundUnit then
        local total = FriendlyUnitsAroundUnit(unit, tonumber(distance))
        return total
    end
    return 0
end)
```

*Usage and Explanation:*
Utilizes smart unlocker to calculate friendlies around target.
Example:


```
{ "Spell", "target.area(10).friendly >= 10" },
```

*9_143. ilevel*
Raw Excerpt:


```
ProbablyEngine.condition.register("ilevel", function(unit, _)
    return math.floor(select(1,GetAverageItemLevel()))
end)
```

*Usage and Explanation:*
Returns iLevel against integer
Example:


```
{ "Spell", "player.ilevel >= 600" },
```

*9_144. firehack*
Raw Excerpt:


```
ProbablyEngine.condition.register("firehack", function(unit, _)
    return FireHack or false
end)
```

*Usage and Explanation:*
Bool check for firehack.
Example:


```
{ "Spell", "player.firehack" },
```

[b]9_145. offspring[b]
Raw Excerpt:


```
ProbablyEngine.condition.register("offspring", function(unit, _)
    return type(opos) == 'function' or false
end)
```

*Usage and Explanation:*
Returns boolcheck for offspring
Example:


```
{ "Spell", "player.offspring" },
```

----------


## ImogenOC

*10. States*

*10_0. PREAMBLE*
States are used for PvP, and by EN clients only. Yes it's rude, but we need people to localize seeing as we cant. Use with the standard target vars
*10_1. state.purge*
Can be dispelled. Similar to 9_1

*10_2. state.charm*
Currently charmed

*10_3. state.disarm*
Currently disarmed

*10_4. state.disorient*
Currently disoriented

*10_5. state.dot*
Currently has a damage over time effect

*10_6. state.fear*
Currently feared

*10_7. state.incapacitate*
Currently incapacitated

*10_8. state.misc*
Checks for: "unable to act", "^bound", "^frozen.$", "^cannot attack or cast spells", "^shackled.$" in tooltip.

*10_9. state.root*
Curently rooted

*10_10. state.silence*
Currently silenced

*10_11. state.sleep*
Currently asleep

*10_12. state.snare*
Currently snared

*10_13. state.stun*
Currently stunned

*10_14. immune.all*
Has one of the following effects: "dematerialize", "deterrence", "divine shield", "ice block"

*10_15. immune.charm*
Has one of the following effects: "bladestorm", "desecrated ground", "grounding totem effect", "lichborne"

*10_16. immune.disorient*
Has one of the following effects: "bladestorm", "desecrated ground"

*10_17. immune.fear*
Has one of the following effects: "berserker rage", "bladestorm", "desecrated ground", "grounding totem", "lichborne", "nimble brew"

*10_18. immune.incapacitate*
Has one of the following effects: "bladestorm", "desecrated ground"

*10_19. immune.melee*
Has one of the following effects: "dispersion", "evasion", "hand of protection", "ring of peace", "touch of karma"

*10_20. immune.silence*
Has one of the following effects: "devotion aura", "inner focus", "unending resolve"

*10_21. immune.polly*
Has one of the following effects: "immune to polymorph"

*10_22. immune.misc*
Has one of the following effects: "bladestorm", "desecrated ground"

*10_23. immune.sleep*
Has one of the following effects: "bladestorm", "desecrated ground", "lichborne"

*10_24. immune.snare*
Has one of the following effects: "bestial wrath", "bladestorm", "death's advance", "desecrated ground", "dispersion", "hand of freedom", "master's call", "windwalk totem"

*10_25. immune.spell*
Has one of the following effects: "anti-magic shell", "cloak of shadows", "diffuse magic", "dispersion", "massspell reflection", "ring of peace", "spell reflection", "touch of karma"

*10_26. immune.stun*
Has one of the following effects: "bestial wrath", "bladestorm", "desecrated ground", "icebound fortitude", "grounding totem", "nimble brew"

----------


## ImogenOC

YOU REACHED THE END. THIS POST IS RESERVED.
IM SO STONED, THIS TOOK 8 HOURS.

I should make dinner...

----------


## Vengfull

Holyyyyyyyyyy.............. Great dox

----------


## svs

Great job Imo!  :Smile:

----------


## temp123

Finally! Good work and thank you

----------


## ImogenOC

> Holyyyyyyyyyy.............. Great dox





> Great job Imo!





> Finally! Good work and thank you


*rubs eyes*
My pleasure.

----------


## -Ryuk-

Thanks for mentioning Caelus.

Ive PM'd you, hopefully we can work together.

----------


## thefrobel

UGH, Finally.... ;-)

----------


## bashor

Thank you for this very big docu!!

Is it possible to add some informations how to adjust the generic.lua? 

I am on a mac os x and want to have some functions like "target.ground" or "player.ground".

----------


## StinkyTwitch

bashor you need an unlocker that has object management to use those. that's why its in the generic the way it is.

----------


## ImogenOC

> Thank you for this very big docu!!
> 
> Is it possible to add some informations how to adjust the generic.lua? 
> 
> I am on a mac os x and want to have some functions like "target.ground" or "player.ground".


See below




> bashor you need an unlocker that has object management to use those. that's why its in the generic the way it is.


Check out the mac unlocker I linked.

----------


## bashor

The mac unlocker doesn't have advanced features atm (ProbablyEngine shows that and the functions don't work too). 
I was thinking about scripting it, but it seems to be more difficult than I thought.

Nethertheless many thanks for your work.

----------


## ImogenOC

> The mac unlocker doesn't have advanced features atm (ProbablyEngine shows that and the functions don't work too). 
> I was thinking about scripting it, but it seems to be more difficult than I thought.
> 
> Nevertheless many thanks for your work.


JuJuBoSc is actively working to re-mediate that.  :Wink:

----------


## PrettyStandard

Yo you went ham on this nice job yo

----------


## gomisensei

good job, we all appreciate the work you put in to this. a few notes, however.

[b]9_55. classification/b] missing [ and classification is misspelled

----------


## ImogenOC

> good job, we all appreciate the work you put in to this. a few notes, however.
> 
> [b]9_55. classification/b] missing [ and classification is misspelled


Thanks! Updated that.



> Yo you went ham on this nice job yo


My pleasure. ^^

----------


## MrBrain1

great work.

does "player.buff.count(Lunar Empowerment,1)" work? its missing in the doc, i used "player.buff(Lunar Empowerment1).count = 1"

and whats going on with aura.stacks?  :Smile:

----------


## ImogenOC

> great work.
> 
> does "player.buff.count(Lunar Empowerment,1)" work? its missing in the doc, i used "player.buff(Lunar Empowerment1).count = 1"
> 
> and whats going on with aura.stacks?


Should be player.buff(BuffName).count (COMPARATOR) INTEGER

Dont ask me about auras, I hardly understand the system. Talk to hack for accurate info.

----------


## Jaladhjin

> *3_5. Git / SVN*
> Yup!
> https://gitlab.com/probablyengine/probably
> TurtleSVN should allow you to update straight from there, else use any normal git program.


I'm not givin' yuh crap about it.. don't care if you don't.. buuut just for the sake of clarification I assume you mean "Tortoise"SVN ;-)

TortoiseSVN - Home

----------


## ImogenOC

> I'm not givin' yuh crap about it.. don't care if you don't.. buuut just for the sake of clarification I assume you mean "Tortoise"SVN ;-)
> 
> TortoiseSVN - Home

----------


## adde88

I'm so grateful for this documentation. It has helped me so much!
I don't think i can thank you enough! +rep!!!

----------


## Nimesil

{ "73510", "player.buff(Surge of Darkness)" }, -- Mind Spike

not workin in RU client, even if i change name to ID,
any chance to fix this?
ps: changing to RU name not working too

----------


## MrBrain1

> { "73510", "player.buff(Surge of Darkness)" }, -- Mind Spike
> 
> not workin in RU client, even if i change name to ID,
> any chance to fix this?
> ps: changing to RU name not working too


should work, code is fine, try using spellid in player.buff, with ru client, there are 3 buffs so you need to find the right spellid. 
Surge of Darkness - Wowhead Search

check if any errors are in the lines above this code, does your debugger spit anything out?

----------


## thrakmar

This documentation is so good. Very helpful

----------


## gomisensei

spell.cooldown is NOT boolean, it returns seconds left in cooldown, or 0 if spell is NOT on cooldown. Please Modify guide accordingly.

----------


## StinkyTwitch

As far as I know Imogen hasn't been here in months.

----------


## darkjacky

> spell.cooldown is NOT boolean, it returns seconds left in cooldown, or 0 if spell is NOT on cooldown. Please Modify guide accordingly.


You are supposed to do spell.cooldown < seconds. That way you create a boolean.
Lua will turn anything higher than 0 or lower than 0 into true. false = false, nil = false, 0 = false the rest is true.

Now I do agree that if the guide says it is a boolean it should be edited.

----------


## gomisensei

Also, interruptAt syntax is incorrect, you use target.InterruptAt(xx) as a replacement for modifier.interrupt, not as a comparator.

----------


## cs0267

Maybe I'm not seeing it and it's there... but anyhow, does anyone know how i can get it to stop my player from channeling to cast another spell when its on cd?

----------


## gomisensei

> Maybe I'm not seeing it and it's there... but anyhow, does anyone know how i can get it to stop my player from channeling to cast another spell when its on cd?


if you prefix the spell name with a ! (i.e. "!Spellsteal") i believe it will interrupt whatever is being casted to cast the new spell, not sure if it will cancel a channel, but you could try...

----------


## cs0267

> if you prefix the spell name with a ! (i.e. "!Spellsteal") i believe it will interrupt whatever is being casted to cast the new spell, not sure if it will cancel a channel, but you could try...


Thanks! I gave that a try and now it stops channeling when any spell comes off cooldown (which is what I want), but then it starts channeling again.  :Smile:

----------


## cs0267

I got it... put the ! in front of the spellid you want to cast not the spellid you want to stop channeling. Thanks! you were very helpful!

----------


## StinkyTwitch

just be careful with ! usage. It will interrupt anything you are currently doing to cast that spell if its conditions are met. This means even if you are already casting/channeling something.

----------


## cs0267

So what is the proper usage? I just want it to stop channeling mind flay when mind blast is off cd. Right now it is working correctly for me, but any advice would be helpful.

----------


## StinkyTwitch

Don't change anything if its working, just be mindful if you notice stuff like getting interrupted that that may be the issue.

----------


## Shark5060

How exactly do I use "casting.time"?

If I wanted to cast "Aimed Shot" if the Casttime is lower than the remaining debuff duration of Vulnerable, how would the syntax have to look like?
{ "Aimed Shot", { "player.casting.time(Aimed Shot) < target.debuff(Vulnerable).duration", "player.focus > 80" } },

does not work

----------


## todor0033

where i can downaload please tell me and work for private server warmane mop ?

----------


## todor0033

please for private server update and for legion !!

----------


## rossi123

> *10. States*
> 
> *10_0. PREAMBLE*
> States are used for PvP, and by EN clients only. Yes it's rude, but we need people to localize seeing as we cant. Use with the standard target vars
> *10_1. state.purge*
> Can be dispelled. Similar to 9_1
> 
> *10_2. state.charm*
> Currently charmed
> ...


please i have a question why States are used for PvP, and by EN clients only ? why the others can't use it

----------


## seoking

> *10. States*
> 
> *10_0. PREAMBLE*
> States are used for PvP, and by EN clients only. Yes it's rude, but we need people to localize seeing as we cant. Use with the standard target vars
> *10_1. state.purge*
> Can be dispelled. Similar to 9_1
> 
> *10_2. state.charm*
> Currently charmed
> ...


Can you please explain a bit more about it? i'm a bit confused and have certain doubts

9Apps Vidmate APK Cartoon HD

----------


## barryallen1337

hi, i have downloaded the client from the downloads section, MoP client, not the old, and when i execute the wow.exe not starting, in the Task manager just appear like its open or starting, but nothing happens. I have a different client with the WoD models and works allmost fine, have some bugs and crash, and some texture missings, so this is the reason i was trying to download this one, and one friend have the same problem... Any ideas? Shareit VidMate App - Download Install Best Video Downloader VidMate APK 2019

----------


## Totoy Tulog

I could not get this to work.

I want to cast "Enveloping Mist" when I am Channeling Soothing Mist.

I tried any one of this. Not working.



> { "Enveloping Mist",{ "player.buff(115175)", "player.chi >= 3" }},





> { "Enveloping Mist",{ "player.channeling(115175)", "player.chi >= 3" }},





> { "Enveloping Mist",{ "player.casting(115175)", "player.chi >= 3" }},


Found another way.
{ "/cast Enveloping Mist", {"player.casting(Soothing Mist)", "player.chi >= 3"} },

----------


## dorbloom100

Thanks for this detail finally i got it .







omegle online

----------


## StorePlayApk

Intro Maker Mod Apk
Funimate Pro Mod Apk
Blue Kinemaster Pro Mod Apk
Octopus Mod Apk Premium
StorePlay Apk
StatusVideoApp
IdleMod

----------


## BagFuse

The mac unlocker doesn't have advanced features atm (ProbablyEngine shows that and the functions don't work too). I was thinking about scripting it, but it seems to be more difficult than I thought. Nethertheless many thanks for your work. 
Damon PS2 Pro Emulator APK

----------

