ONLY WORKS ON PATCH 5.1 AND HIGHER
This addon requires TensorCore! Make sure you have that installed from the Minion store.
For optimal performance, you must set your pulse rate to 50ms or lower. As such, this addon by default will set your pulse rate to 50.
Join https://discord.gg/bVABzBA for support and reactions. Check the #files channel for profiles that have been shared publicly.
If you are a new user, please watch this video first: https://www.youtube.com/watch?v=iyo0hs5_-dA
TensorReactions is a fully-featured and extremely optimized reactions system, that incorporates both timelines for savage and ultimate raids, as well as more traditional event-based reactions.
Notable featuers:
This addon is huge in scope, and covering everything in this wiki is impossible. I have provided basic usage information and examples, however you should go and experiment with the various options
General theme with the UI is to right click when in doubt
Timeline - This is the fight for which you add reactions for.
Trigger Profile - This the trigger profile for the selected fight. Contains all your reactions. To swap between profiles you just select a different one in this dropdown.
Next, going left to right, top to bottom with the ui elements:
Timeline List - Has all the mechanics in the selected fight. You can right click on any element in this list to copy/paste the entire set of reactions, or remove all the reactions entirely.
Mechanic Info Panel - Has some useful information for the selected mechanic
Conditions - Has a list of conditions. These cannot be reordered, and have indexes so you know which one is which.
Actions - List of actions that will be executed in that reaction. The actions are executed in that exact priority, and ogcds/gdcs are weaved correctly depending on priority. Note: Priority =/= order! If you want to execute a sequence of actions, you need a last skill check on each action. For more info, please see the examples and/or ask in the discord.
Name: Can be changed to whatever you want, duplicates are allowed (internal uuid system is used)
Timer Offset: Relative to the selected mechanic, when the reaction will be executed. For example, if the selected mechanic time is 247.6, a timer offset of -4 will use that reaction 4s before that mechanic, at 243.6s. The timer offset has a 2.5s window to execute the reaction before it will be dequeued as stale. I recommend using Timer Offset for instant actions such as variables and misc reactions.
Use Time Range: Select the window of time for when the reaction will be attempted to be used. For example, a Timer Start Offset of -5 and a Timer End Offset of 5 will attempt to execute the reaction starting from 5s before the mechanic and until 5s after the mechanic. If the time of the mechanic is at 247.6, the reaction will be attempted to be executed starting at 242.6 and until 252.6. I recommend using Time Range for Skill overrides that are manually used by TensorReactions, so that you have enough time for the action to go off.
Loop Reaction: Every reaction will run only once for that given pull, however loop reaction will run it continuously in the window it's set to be executed in. By default, the timer offset window is 2.5s, and the Time Range window is whatever you set it to be. I highly reocmmend using this in conjunction with the Time Range option for reactions to continuously execute before a given mechanic. For example, a reaction would continuously heal low hp players starting from -30s until -5s, using an action priority that will end on the highest priority action.
Lua: Each lua reaction will have 3 variables that it can use (and one that it must):
self: the reaction object. You must set self.used = true if the reaction successfully went off and can be dequeued!
data: Global table passed to every lua reaction, condition, and action, gets reset on wipe! This table is useful for checking variables set by other lua reactions as well as setting them. For example: a lua reaction that would check
if data.lastUse == nil or TimeSince(data.lastUse) > 500 then data.lastUse = Now() self.used = true end
would add a 500ms delay to this reaction.
You can also invoke the ACR override by returning the following from your lua code:
table action, number targetID, bool ignoreWeaveRules, bool allowInterrupt
Argument action must be a valid action from the ActionList. If you choose to return an action from lua, make sure the “Lua Returns Action” box is checked!
The way this list works is, you create your conditions here, and then link them to specific actions below. That way you can have multiple actions using the same condition without having to make a new condition every time. Every action will also have it's own independent list of linked conditions.
Category: General category that exposes more options. Self contains most of the important ones, such as Gauge, Map ID, Skill Cooldown checks, etc, however I encourage you to explore the options and ask in the discord if you don't understand any of them.
Action CD: This list will only show actions that are usable by your current job and level. You can, of course, switch jobs and it will display the actions for that job. Once the action is set, it is stored regardless of job, so you don't need to worry about switching jobs and losing the set skill
Emnity: This value is target.aggropercentage on your current target.
Filter: Filter condition will loop over your target list and set detection target, then run your conditions. In the linked conditions to filter, you must set detection target to be the target you are checking on (party > target: detection target), and then once it's done it will look at the list of all targets that match, pick a subtype, and then set that as detection target. Then you link your skill action and use detection target as your target, with the filter condition linked. Tip: You can set “min number of entities” to 0, and enable “match all”, and effectively this will become an “OR” condition. Setting min entities to 0 just means reactions will ignore your target list and simply evaluate the conditions as is.
Lua: If you make a lua reaction, you must return a boolean, else your condition will be ignored. Important variables that you can use:
data: Global table passed to every lua reaction, condition, and action, gets reset on wipe! This table is useful for checking variables set by other lua reactions. For example: a lua reaction that would check
return data.lastUse ~= nil and TimeSince(data.lastUse) > 500
would add a 500ms delay to any action that used this condition.
Skill: This will call the action override system that works with any acr / skillmgr profile and will follow gcd/ogcd weaving rules.
Interrupt Channels: This will interrupt channels to use your ability. If Interrupt Channels is checked, OGCDs will automatically ignore ogcd rules regardless of the “Ignore Weave Rules” setting!
Ignore Weave Rules: OGCD Will ignore weave rules and will be allowed usage during a gcd window. Example usage: Emergency Tactics into adlo on sch, using reassemble/queen before boss is targettable on mch.
Untarget: Untargets enemy. Will not show if Set Target is checked.
Set Target: Targets an enemy. Will not show if Untarget is checked.
Condition List: List of conditions that the action will check. Each condition must be satisfied for the action to execute. This list can be dragged and dropped, you can also right click on the condition to view options.
Lua: There are 3 useful variables that you can (and one that you must) use here.
self: the action object. You must set self.used = true if the action successfully went off and can be dequeued!
data: Global table passed to every lua reaction, condition, and action, gets reset on wipe! This table is useful for checking variables set by other lua reactions as well as setting them. For example: a lua action that executes the following code:
local target = TensorCore.getEntityByGroup("Main Tank") local minne = ActionList:Get(1, 7408) if minne.cdmax - minne.cd < 1.0 and target~= nil then ACR_TensorRequiem_Hotbar_NaturesMinne_Custom = true ACR_TensorRequiem_Hotbar_NaturesMinne_Custom_TargetID = target.id self.used = true end
would invoke the hotbar method inside of TensorRequiem to use natures minne on your main tank.
You can also invoke the ACR override by returning the following from your lua code:
table action, number targetID, bool ignoreWeaveRules, bool allowInterrupt
Argument action must be a valid action from the ActionList. If you choose to return an action from lua, make sure the “Lua Returns Action” box is checked!
Profile: This is the profile that will be loaded. General reactions are loaded regardless of timeline and map, hence the name “general”.
Each reaction in this list will be executed in the order of the listing and depending on event. The UI is the same as Timeline Reactions but with a few minor tweaks.
Event: List of events to trigger your event with. OnUpdate should be used as a last resort, as it's a bit resource heavy depending on the reaction.
Lua: every lua reaction and action inside general reactions will have the same variables as the timeline ones, however they will also have an additional variable, eventArgs:
self: the same as timelines, which means for lua reactions and lua actions, self.used must be set if the (re)action goes off successfully
data: same as timelines, for you to use as you wish. This data variable may prove very useful in general reactions as you can set it based on certain events happening. For example: on limit cut in TEA, you get marker number 5. You can use the OnEntityMarkerAdd event and see which marker is added on you, and store that in a data.myLimitCutNumber variable. You can use that variable to use certain skills in the timeline for tea (remember that data object is shared between everything, general timeline reactions included
eventArgs: this is the new arg for general lua reactions/actions/conditions. It is a table, and each key is different for each event (listed below). Example usage: d(eventArgs.entityID)
You can also invoke the ACR override by returning the following from your lua code:
table action, number targetID, bool ignoreWeaveRules, bool allowInterrupt
Argument action must be a valid action from the ActionList. If you choose to return an action from lua, make sure the “Lua Returns Action” box is checked!
TensorReactions_CurrentTimer
OnUpdate
: no args, simply an event that runs every frameOnEntityCast
: Triggered the moment an entity casts an instant cast action, or successfully finishes a channel actionOnEntityChannel
: Triggered the moment an entity starts channeling an actionOnEntityMarkerAdd
: Triggered whenever a marker is added above an entity (stack marker etc). I recommend making a debug trigger on this one so you can find out the marker types, or ask in the discord.OnEntityAdd
: Triggered whenever a new entity is added/loaded in. Useful for detecting when add spawns happen. These will also trigger on reset so you should have a combat check on any entity add/remove reactions.OnEntityRemove
: Triggered whenever an entity is removed/unloaded. This is not the same as when an entity dies, often an entity will die but still exist for a 5-10 seconds after These will also trigger on reset so you should have a combat check on any entity add/remove reactions.OnNewChatLine
: Triggered whenever a new chat message is sent, including combat log. Useful for detecting certain phase transitions and various misc reactionsOnNewBuffEntry
: Triggered whenever a buff is added to an entityOnWipe
: no args, simply gets triggered when you go out of combat, and only gets triggered if a valid timeline is loaded to prevent situations like dungeons constantly triggering onwipe()italics = type, underline = optional
TensorCore.isAnyEntityCasting(number castid, string elistFilters)
castid
, and table entity that is channeling castid
. Optionally, elistFilters can be specified to check a more narrow list of entities.TensorCore.isEntityAlive(number contentid, string elistFilters)
contentid
is alive, and table entity that is matches contentid
and is alive. Optionally, elistFilters can be specified to check a more narrow list of entities.TensorCore.getEntityByGroup(string strGroup, string or table subGroup, bool inParty, number range, number szCluster)
{name = “Striking Dummy”, subgroup = “Nearest”, contentid = 541}
. Important note: you don't need contentid if strGroup is “Named Target”, and you don't need name if strGroup is “ContentID”. Subgroup will default to nearest in all cases.{“All”, “Self”, “Named Target”, “ContentID”, “Current Target”, “Enemy”, “Target of Current Target”, “Target Spell of Current Target”, “Most Clustered Ally”, “Most Clustered Enemy”, “Party”, “Main Tank”, “Off Tank”, “Tank”, “Melee DPS”, “Ranged DPS”, “Ranged Physical DPS”, “Ranged Caster DPS”, “Healer”}
{“Nearest”, “Lowest HP”, “Highest HP”, “Number”}
Important Note: Number will simply return the list of strGroup targets back to you.{“Named Target”, “Enemy”, “Party”, “Tank”, “ContentID”, “Melee DPS”, “Ranged DPS”, “Ranged Physical DPS”, “Ranged Caster DPS”, “Healer”, “Target Spell of Current Target”}
TensorCore.resetTTKTargets(number …)
TensorCore.resetTTKTargets(123, 456)
. This will reset ttk info on entities with id 123 and 456.