Last active
August 29, 2015 14:10
-
-
Save StinkyTwitch/2ba6098796652884b552 to your computer and use it in GitHub Desktop.
AutoTarget Drop In Module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- version: 0.9 | |
-- This variable is here just for testing purposes while I/we verify the code works correctly in | |
-- all situations. Will eventually not be needed. | |
GRunAutoTargetCode = false | |
-- Our main table for storing the objects and their distance from the player. | |
-- The table looks like this: [index] [object_pointer_address] [distance_to_player] | |
-- The table is sorted by distance to the player. | |
-- To get the object pointer use "GUnitCache[i].key" | |
GUnitCache = {} | |
--[[------------------------------------------------------------------------------------------------ | |
GLOBAL TABLE OF SPECIAL CASE TARGETS | |
* Credit: MrTheSoulz for the framework | |
--------------------------------------------------------------------------------------------------]] | |
GSpecialTargets = { | |
-- TRAINING DUMMIES | |
31144, -- Training Dummy - Lvl 80 | |
31146, -- Raider's Training Dummy - Lvl ?? | |
32541, -- Initiate's Training Dummy - Lvl 55 (Scarlet Enclave) | |
32542, -- Disciple's Training Dummy - Lvl 65 | |
32545, -- Initiate's Training Dummy - Lvl 55 | |
32546, -- Ebon Knight's Training Dummy - Lvl 80 | |
32666, -- Training Dummy - Lvl 60 | |
32667, -- Training Dummy - Lvl 70 | |
46647, -- Training Dummy - Lvl 85 | |
60197, -- Scarlet Monastery Dummy | |
67127, -- Training Dummy - Lvl 90 | |
87761, -- Dungeoneer's Training Dummy <Damage> | |
88314, -- Dungeoneer's Training Dummy <Tanking> | |
88316, -- Training Dummy <Healing> | |
89078, -- Training Dummy (Garrison) | |
87318, -- Dungeoneer's Training Dummy <Damage> | |
-- WOD DUNGEONS/RAIDS | |
75966, -- Defiled Spirit (Shadowmoon Burial Grounds) | |
76518, -- Ritual of Bones (Shadowmoon Burial Grounds) | |
81638, -- Aqueous Globule (The Everbloom) | |
} | |
--[[------------------------------------------------------------------------------------------------ | |
GLOBAL TABLE OF IMMUNE AURAS | |
* Credit: MrTheSoulz for the framework | |
--------------------------------------------------------------------------------------------------]] | |
GImmuneAuras = { | |
-- CROWD CONTROL | |
118, -- Polymorph | |
1513, -- Scare Beast | |
1776, -- Gouge | |
2637, -- Hibernate | |
3355, -- Freezing Trap | |
6770, -- Sap | |
9484, -- Shackle Undead | |
19386, -- Wyvern Sting | |
20066, -- Repentance | |
28271, -- Polymorph (turtle) | |
28272, -- Polymorph (pig) | |
49203, -- Hungering Cold | |
51514, -- Hex | |
61025, -- Polymorph (serpent) -- FIXME: gone ? | |
61305, -- Polymorph (black cat) | |
61721, -- Polymorph (rabbit) | |
61780, -- Polymorph (turkey) | |
76780, -- Bind Elemental | |
82676, -- Ring of Frost | |
90337, -- Bad Manner (Monkey) -- FIXME: to check | |
115078, -- Paralysis | |
115268, -- Mesmerize | |
-- MOP DUNGEONS/RAIDS | |
106062, -- Water Bubble (Wise Mari) | |
110945, -- Charging Soul (Gu Cloudstrike) | |
116994, -- Unstable Energy (Elegon) | |
122540, -- Amber Carapace (Amber Monstrosity - Heat of Fear) | |
123250, -- Protect (Lei Shi) | |
143574, -- Swelling Corruption (Immerseus) | |
143593, -- Defensive Stance (General Nazgrim) | |
} | |
--[[------------------------------------------------------------------------------------------------ | |
CHECK SPECIAL TARGET | |
* Credit: MrTheSoulz for the framework | |
--------------------------------------------------------------------------------------------------]] | |
function CheckSpecialTarget(unit) | |
-- Check if the unit supplied exists. | |
if not UnitExists(unit) then | |
return false | |
-- If the unit exists then check to see if it has a valid GUID. | |
elseif UnitGUID(unit) then | |
-- Take the GUID and strip it out for the ID and convert it to a number. | |
targets_guid = tonumber(string.match(UnitGUID(unit), "-(%d+)-%x+$")) | |
-- If the GUID is not valid default to 0. | |
else | |
targets_guid = 0 | |
end | |
-- Loop through the special targets Global table. | |
for i=1, #GSpecialTargets do | |
-- If we find a matching GUID between our target and the table then this is a special target. | |
if targets_guid == GSpecialTargets[i] then | |
return true | |
end | |
end | |
-- Otherwise we return false, not a special target. | |
return false | |
end | |
--[[------------------------------------------------------------------------------------------------ | |
CHECK AURA TABLE | |
* Credit: MrTheSoulz for the framework | |
--------------------------------------------------------------------------------------------------]] | |
function CheckAuraTable(unit, spells_table) | |
-- Loop through the number of possible buffs on a target (40). Will break whenever it gets to | |
-- the end of the buff list (1st nil value). Will not ALWAYS scan through 40. | |
for i = 1, 40 do | |
-- Get the spellID of each buff on the unit. | |
local _,_,_,_,_,_,_,_,_,_,spell_id = UnitAura(unit, i) | |
-- Loop through our Immune CC Spell table (v) for each unit scanned (k). | |
for k,v in pairs(spells_table) do | |
-- If we find a match between the unit and our spell table then return true. | |
if spell_id == v then | |
return true | |
-- Otherwise return false | |
else | |
return false | |
end | |
end | |
end | |
end | |
--[[------------------------------------------------------------------------------------------------ | |
CHECK IMMUNE TARGET | |
* Credit: MrTheSoulz for the framework | |
--------------------------------------------------------------------------------------------------]] | |
function CheckImmuneTarget(unit) | |
-- If we can't attack the 'unit' then the target is considered immune. | |
if not UnitCanAttack("player", unit) then | |
return true | |
-- If the 'unit' is not in combat and not a special target then it is considered immune. | |
elseif not UnitAffectingCombat(unit) and not CheckSpecialTarget(unit) then | |
return true | |
-- If the 'unit' is effected by CC then it is considered immune. | |
elseif CheckAuraTable(unit, GImmuneAuras) then | |
return true | |
-- Otherwise it is not an immune target. | |
else | |
return false | |
end | |
end | |
--[[------------------------------------------------------------------------------------------------ | |
CHECK TARGET IS INFRONT | |
* Credit: MrTheSoulz for the framework | |
--------------------------------------------------------------------------------------------------]] | |
function CheckTargetIsInFront(unit) | |
-- 3d position of target. | |
local aX, aY, aZ = ObjectPosition(unit) | |
-- 3d position of player. | |
local bX, bY, bZ = ObjectPosition("player") | |
-- Get the "players" orientation in radians. 0 being North. | |
local player_facing = GetPlayerFacing() | |
-- The orientation of in terms of North between the "player" and "target". | |
local facing = math.atan2(bY - aY, bX - aX) % 6.2831853071796 | |
-- Check if the "player" is within a 90 degree arc of facing the "target". Imagine drawing a | |
-- straight line from the center of the "player" to the center of the "target". Then check if | |
-- the "players" current orientation (field of view for attacking) is within 90 degrees of that. | |
return math.abs(math.deg(math.abs(player_facing - (facing))) - 180) < 90 | |
end | |
--[[------------------------------------------------------------------------------------------------ | |
AUTO TARGET | |
* Credit: MrTheSoulz for the framework | |
--------------------------------------------------------------------------------------------------]] | |
function AutoTarget() | |
-- Check if the "player" already has a target and that target is not dead or a ghost. | |
if UnitExists("target") and not UnitIsDeadOrGhost("target") then | |
return false | |
end | |
-- Loop through the object table. | |
for i=1,#GUnitCache do | |
-- Check that the current object in the table (GUnitCache[i].key) is not immune. | |
if not CheckImmuneTarget(GUnitCache[i].key) then | |
-- Check that the current object in the table (GUnitCache[i].key) is in front of the | |
-- player. | |
if CheckTargetIsInFront(GUnitCache[i].key) then | |
-- Run the macro "/target OBJECT". Because we now sort Object table based on | |
-- distance this will always select the nearest VALID target. Much joy was had in | |
-- writting this! | |
return Macro("/target "..GUnitCache[i].key) | |
end | |
end | |
end | |
-- Otherwise auto target should fail. | |
return false | |
end | |
--[[------------------------------------------------------------------------------------------------ | |
UNIT CACHE | |
* Credit: Mirakuru and MrTheSoulz for the framework | |
--------------------------------------------------------------------------------------------------]] | |
function Cache() | |
-- Wipe the table each read. | |
wipe(GUnitCache) | |
-- Get the total number of objects in the "player's" sphere of influence. | |
local total_objects = ObjectCount() | |
-- Loop through the total number of objects. | |
for i=1, total_objects do | |
-- Assign the pointer for the current object. | |
local object = ObjectWithIndex(i) | |
-- If the current object exists... | |
if ObjectExists(object) then | |
-- If the current object is a unit, is within 40 yards of the player and is considered | |
-- alive then... | |
if ObjectIsType(object, ObjectTypes.Unit) | |
and ProbablyEngine.condition["distance"](object) <= 40 | |
and ProbablyEngine.condition["alive"](object) | |
then | |
-- Get the player's position. | |
local x1, y1, z1 = ObjectPosition("player") | |
-- Get the object's position. | |
local x2, y2, z2 = ObjectPosition(object) | |
-- Trig. | |
local dx = x2 - x1 | |
-- Trig. | |
local dy = y2 - y1 | |
-- Trig. | |
local dz = z2 - z1 | |
-- Distance from player to target in yards. | |
local distance = math.sqrt((dx*dx) + (dy*dy) + (dz*dz)) | |
-- Store the object's pointer address as a string. | |
local obj_text = tostring(object) | |
-- Insert the VALID objects pointer address and it's distance from the player | |
-- into the cache table. | |
table.insert(GUnitCache, {key=obj_text, value=distance}) | |
-- Sort the table so that the closest VALID objects are first. | |
table.sort(GUnitCache, function(a,b) return a.value < b.value end) | |
end | |
end | |
end | |
end | |
--[[------------------------------------------------------------------------------------------------ | |
CACHE UPDATE TIMER | |
* Credit: MrTheSoulz | |
* Requires that you have an 'autotarget' custom toggle in your rotation file: | |
ProbablyEngine.toggle.create( | |
'autotarget', | |
'Interface\\Icons\\ability_hunter_snipershot', | |
'Auto Target', | |
'Automatically target the nearest enemy when target dies or does not exist' | |
) | |
* Requirement #2: You need to add the following to your rotation somewhere in the function for | |
custom toggles, "GRunAutoTargetCode = true". This turns on the code for the ticker. You will | |
still be able to turn on/off auto targetting using the toggle. This is only necessary as I test | |
this new code out so that I can stop it from running if its breaking. | |
This is what your custom toggle code should look like at the end of your rotation if it was the | |
only toggle. | |
function() | |
ProbablyEngine.toggle.create( | |
'autotarget', | |
'Interface\\Icons\\ability_hunter_snipershot', | |
'Auto Target', | |
'Automatically target the nearest enemy when target dies or does not exist' | |
) | |
GRunAutoTargetCode = true | |
end | |
--------------------------------------------------------------------------------------------------]] | |
C_Timer.NewTicker(0.1, (function() | |
if GRunAutoTargetCode then | |
if ProbablyEngine.config.read('button_states', 'MasterToggle', false) | |
and ProbablyEngine.module.player.combat | |
then | |
if ProbablyEngine.config.read('button_states', 'autotarget', false) then | |
AutoTarget() | |
end | |
Cache() | |
end | |
end | |
end), nil) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* Requires that you have an 'autotarget' custom toggle in your rotation file: | |
ProbablyEngine.toggle.create( | |
'autotarget', | |
'Interface\\Icons\\ability_hunter_snipershot', | |
'Auto Target', | |
'Automatically target the nearest enemy when target dies or does not exist' | |
) | |
* Requirement #2: You need to add the following to your rotation somewhere in the function for | |
custom toggles, "GRunAutoTargetCode = true". This turns on the code for the ticker. You will | |
still be able to turn on/off auto targetting using the toggle. This is only necessary as I test | |
this new code out so that I can stop it from running if its breaking. | |
This is what your custom toggle code should look like at the end of your rotation if it was the | |
only toggle. | |
function() | |
ProbablyEngine.toggle.create( | |
'autotarget', | |
'Interface\\Icons\\ability_hunter_snipershot', | |
'Auto Target', | |
'Automatically target the nearest enemy when target dies or does not exist' | |
) | |
GRunAutoTargetCode = true | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment